graphene-django
Published October 20, 2021
This video features Adem Gaygusuz, Brad Martsberger, Caleb Collins-Parks, Dane Hillard, Dr. Russell Keith-Magee, Jeremy Gatens, Kojo Idrissa, Laura Lorenz, Micah Lyle and Vince Salvino at DjangoCon US 2019 in San Diego, California, USA.
DjangoCon 2019 - Lightning Talks by Kojo Idrissa
Adem Gaygusuz 00:00
Laura Lorenz 5:24
Micah Lyle 10:23
Vince Salvino 15:14
Russell Keith-Magee 20:24
Brad Martsberger 25:19
Jeremy Gatens 30:21
Dane Hillard 35:31
Caleb Collins-Parks 40:27
This talk was presented at: https://2019.djangocon.us/talk/lightning-talks/
LINKS:
Follow Kojo Idrissa 👇
On Twitter: https://twitter.com/Transition
Official homepage: http://kojoidrissa.com/
Follow DjangCon US 👇
https://twitter.com/djangocon
Follow DEFNA 👇
https://twitter.com/defnado
https://www.defna.org/
Intro music: "This Is How We Quirk It" by Avocado Junkie.
Video production by Confreaks TV.
Captions by White Coat Captioning.
The speakers showed practical ways to extend Django and Python: tracking leaked paid data with event logging and user-specific watermarks, testing JavaScript interfaces with Selenium, and using cached properties to avoid repeated work and database queries. They introduced CodeRed CMS as a ready-to-use Wagtail-based alternative for content sites, and argued that businesses should become “contributor neutral” by supporting the open-source projects they depend on. Other examples covered higher-level Django ORM abstractions, cognitive frameworks for simplifying complex decisions, an SDK-like service client for microservices, and DjangoQL for faster, field-specific admin searches. The recording cuts off during the DjangoQL demonstration.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
Speaker 1: Hello everyone. It's lovely to be here. It's my first time at DjangoCon. Thanks for the warm welcome everyone. My name is Ardem Gagusis. I am a Python and JavaScript developer currently at Credit Suisse. I'm a consultant that moves around quite a lot, so I see a lot of different code bases. I also run a website called BetDynamo, which is what I want to talk about a little bit today. It's uh made by the Almighty Django Web Framework, you might know it. Bet Dynamo is a website all about football statistics, aka soccer in your case. We're all about data, uh content. Our users, this the idea actually came out of um a friend of mine who was tired of losing football bets.
Speaker 1: There's quite a culture in the UK around watching the footy and um putting a a few a few bets on the football and he was tired of losing. He's a bit of a techie himself. He says I I wanna use data to to give me a bit of an edge So our site gives uh our users an edge. Um and They they pay for that data and it's theirs and they they share it and use it. And what I want to talk about today is a tale whereby one of our pay our users um decided to rip us off. and start sharing that data for his own financial gain he or she we don't really know financial gain across the web. This made us quite unhappy. We don't mind people sharing data, but he it
Speaker 1: it was a a clean ripoff. So software pirates, can we catch them? Maybe if we attempt to to track their their behavior Enter Django. A simple model was created to represent the the user's behavior through events. We took things like user agent. IP, it sounds invasive, but they were still in our content. And most importantly, which user ID they were in our system. Exposed by a simple um endpoint. uh post endpoint
Speaker 1: and then a small snippet of JavaScript allowed us to just detect when uh screen grab occurred Um you'll probably notice that it's desktop only, but we could tell from the pirate that he was screen grabbing on desktop. And also it was easier to the majority of our users were Mac on desktop, so we we we went with Mac as a leap of faith. So we we shipped that within an hour because Django is so rapid at doing such things. And then it became a waiting game. Turns out we didn't have to wait long at all. As you can see, this is on my mobile using the awesome Django admin. A stream of events came in and this is specifically people hitting screenshot
Speaker 1: on on their keyboard. This was fascinating. But you're probably thinking it's perfectly fine to screenshot. They're well within their rights. So we thought, well what are we gonna do with this data now? There were were of course some users screen grabbing more frequently than others. So we thought and what and we were and we came to an idea This is a small snippet in Django settings. Takes an environment variable, put this together very quickly, but again, Django allows us to do this, deployed on Heroku, an environment variable that um we convert to a key key value dictionary. The keys were the user IDs that were taking the screen grabs. The values were
Speaker 1: discrete numbers that we defined unique to each user. Next, we we use that config to inject it into the statistics for each user. So if we come into the view and if the user's in the dictionary, we inject a discrete number. As you can probably see where I'm going, when we serve up the statistics to each user, those users would would get a discrete number. So again, it was a waiting game. They post every day, so the they posted and bingo that we had the the the discrete number that that user posted. And we were able to track that back to user ID, track that back to their PayPal account, and then contact them politely to ask them to take down the content.
Speaker 1: And they did in fact take the content down. So what does this prove? Well, we were pretty chuff with our skills at hunting pirates. And you can in fact Oops, you can in fact catch a pirate. Just about. Thank you. I'm Ardim Gay Gisis. Warding of pirates one line with Django at a time. Thank you.
Speaker 2: All right, hi. My name is Laura. I'm gonna explain Selenium really fast. Um I work at Industry Dive, we're hiring I'm also going to talk a little bit about hip test, browser stack, behave and behave Django. Shout out to Lee Xiao from DjangoCon 2018. Gave a great talk last year. You should check it out if you want a slower explanation of that stuff. Um okay, why are we talking about this? We want to test our website's full stack features, meaning we need a JavaScript environment. If you're not on board with this, feel free to tune out. Manual testing, boring, tedious, hard to reproduce. Automated testing, fun, the best, not any of that other stuff. Here's a drunk history version of what was up with Selenium. Uh the internet was invented, yada yada. A group of people made Selenium Core and Selenium RC ability to automate stuff with a JavaScript library. and to uh push stuff, push those directions to remote browsers.
Speaker 2: Other people were working on a way to wrap native uh browser commands instead. They combine forces, so we are now here. We can use Selenium's language-specific APIs to send test directions to local browser or through Selenium Hub to remote browsers. I'll talk a little bit about third-party services for hosting those remote browsers. Remote browsers. There is a future, uh maybe we'll talk about that next year. Um there 's a bunch of infrastructure you could set up, but we're all Django developers, so you'll probably start with static live server test case. Here's the snippet from Django Docs. You'll see here that this gives you access to the self. selenium object inside your test case, which exposes to you the Selenium Python bindings to be able to do these browser activities from Python. So find element by name, send keys, do some click stuff. This is all stuff that comes with Selenium Python that is being abstracted for you
Speaker 2: Maybe you want to do some more stuff. We did. So we subclassed this and put in some stuff that in this case is something we wanted to call something else, a sort located above. Here's some Selenium stuff that we're doing. And maybe you want to implement those on your test side. So here I have a test that uses that subclass using my new assertion in here and also some other Selenium Python stuff. If you keep reading the Selenium Python docs, you'll learn that they talk about something called a page object paradigm. This is basically to create classes that describe what your pages do specifically, so you can write your Selenium abstractions of what your page is supposed to do, how the UI works. in these classes and then over in your test you can instantiate those page objects and call those methods there. So it's a way to sort of abstract it page by page instead of a subclass of your test case.
Speaker 2: Locators is the other thing that those docs are going to talk to you about. So this is an idea that for those given pages, you could create this locators. class that has these attributes that look a little bit like this. That way in your code you can use these terms instead of actually describing the um CSS selectors directly in them. So you can see I'm using them over here. If you are really lucky, maybe front end can tell you what these are and you can just spend all of your time using these attributes over here. But Haven't totally experienced that yet. Uh if you want to run uh stuff on more than one browser than your local browser, maybe you want to use Selenium Hub. This is an example of some uh Docker Compose files that is sort of like a stub of Docker Compose that can set up Chrome and Firefox and Selenium Hub
Speaker 2: so that you can actually run your tests in distributed browsers so you can be running multiple kinds at once. Or you can let someone else hub you, in which case I mean use a tool like Browser Stack, for example, to actually host the remote browsers that you want to run. This is actually showing the output from browser stack, which includes recording a video of your test that you can like play at any time. So that's usually like a really wow experience for people. If you want to go to like the totally next level, this is what we're just starting to get used to now in a year later from the talk that I said inspired this whole thing. is to layer on Gherkin, Behave, and Behave Django to describe your selenium tests in Gherkin syntax. So you can use this type of given whatever, when something, then
Speaker 2: something. This might be described by your stakeholders or by product, and this can actually be auto-generated or uh generated yourself into uh these um implementations. uh which can uh be implementing something in Selenium that actually describes what um these regex matches to these scenarios are. If you want to go step five plus, you can uh actually use this tool called hip test. It's this nice UI that you can use to fill out Gherkin scenarios and auto-generate the stubs for these things and abstract things the things of those into action words. So that you can reuse your code over and over again. A couple super fast tips: use a screen sharing app to VNC into the Selenium process. Feel free to throw in a PDB set trace and then take control as a human if you need to debug.
Speaker 2: Web driver wait is your friend, but sometimes it needs a nudge. We use action change move to element with offset and yes, time dot sleep occasionally. Mocking. js has been a lot harder, but I don't have a lot of time to talk about that. So if you're interested, you can ask me later. Thank you.
Speaker 3: Hi, I'm Micah. I'm a freelance Django engineer. I I do everything variety of work for a variety of clients. Um and I don't want to talk about something that's pretty simple and can really be helpful to speed up your Django code and talk about cache properties. I'm gonna just talk about the difference between a cache property and a property and then show an example usage within a view test and some tests and then show how to use them with existing methods. Methods. So let's dive in. Really simple example. We have a Django model of a person. That person has a first name and a last name. And in this example, we are going to use the famous Bengals NFL receiver, Chad Johnson, who famously changed his name to Chad Ochosinko. So we've got um
Speaker 3: For the first thing, we have the property name property, and the second thing underneath the fields we have the prop the cache property name cache property. So they both run the same code. If we instantiate this person and we print the name property followed by the name cache property, we will get the same result out. Chad Johnson. And then if we change the person's last name to Ochosinko, like Chad famously did, I think in 2008, and we save it, you'll notice that the property is going to print Chad Ochacinko next. But the cache property is actually still gonna print Chad Johnson. That's because cache properties are only run once So the first time you access it within the life cycle of the instance and they do not change. Unless if you look at the bottom, if you really need to, you can delete the cache property and reaccess it and it will re
Speaker 3: Compute. So let's talk about actually a real world example. One of the groups I work with is a healthcare group. And in their reset password view that I happen to do, um you want to get the user from a base encoded 64. um essentially. And instead of doing some function like get underscore user, I figured, well, within the view, if we ever need the user, well the first time we access the user, we're just gonna grab it and And obviously, if something goes wrong translating that base64 ID, we can throw a validation error and it'll just return the correct response in the view. So in the bottom snippet there, you can see self. user is called twice, but that's only gonna actually Run that code once. Um talk about in tests. So also in this code
Speaker 3: base, I was brought in to optimize aspects of the code, and when I was brought in it had about 700 tests, and they use the unit style uh setups. And frequently did stuff like uh above, where you'd have a clinic and two clinic locations each being created in the setup. Now each one of these creations is making at least one database query, but some of the tests weren't actually using the clinic locations. Or one test wasn't using the second clinic location. So it's actually really nice to make these cache properties in the test, which, you know, if one of your test cases actually uses them, since a test case is a new instance. each time. It's only gonna going to create it if you need it. Um a more complex example, if this group had 700 tests and Essentially uh they were they had a superclass that
Speaker 3: set up like four or five groups depending on which aspects of the test we're running. And it looks something like this. And this would be run for every single test. So for all 700 tests, it was making at least four queries doing this. Um in the new code, I created a a sub a superclass up there that essentially made these as cache properties. So it made all these groups as cache properties that upon access would create the relevant group corresponding to the user type. And then for all across all the tests, I actually mocked and or patched group. objects so that when you called group. objects. get name equals say the patient name, it actually used a proxy sort of thing that would call one of these cache properties so that now we weren't necessarily getting all
Speaker 3: we weren't for sure getting all four or five of these queries per test, but rather usually only at most one or two because these were groups were not all being created in tests. So I just wanted to show one other case. of using it on an existing method. So cache properties, you don't have to just use a decorator. You can also use it on an existing method. So in this very simple case, we have the class A with X set to 3 and And then the instance variable y set to five. And notice the method just returns the sum of x and y. Um before Python 3. 6, you had to make it a method, you could call it like a function, but you had to put pass in the same name as the property you were naming. it. But now because of the double underscore set name feature in Python 3. 6 and later, you do not have to do that. So yeah, that's um as of Django 4.
Speaker 3: 0, that's going to be obsolete. So there you go. That's cache properties and that's kind of up what's coming up with Django
Speaker 4: Hi everyone. Um so as a web developer just in general, I'm sure you have probably come across WordPress and maybe have to support it. So I I'm not gonna slag on WordPress. It's a great tool for many different uh purposes, but when you're wielding the power of Django, sometimes it can be frustrating to support something like WordPress. So you know it's kind of the holy grail of can you replace WordPress with Django? We're trying to do that. So many of you have probably heard of Wagtail. And it's super popular right now. It's a really great CMS, but it kind of just gives you the bare bones of a CMS framework. You are free to implement however you want, whatever kind of content you want. It's you know you you develop it yourself. So um I'm going to introduce Code Red
Speaker 4: CMS, which is essentially a layer on top of Wagtail or a distribution of Wagtail you could think of as And we have really you know designed this to kind of be sort of a WordPress replacement. You can change the logo, you can log in and you know get get going right away without any code for kind of informational marketing sites. It's really designed for that. So WordPress has the uh famous five-minute install. So I'm going to do a five-minute install of CodeRed CMS and show you what it looks like. So uh first I would just do pip install code red CMS, which I have already done to avoid any Wi-Fi errors. And then next you would do code red
Speaker 4: CMS start uh your project name, lightning. And you can pass in a few extra options too, but this is going to be very similar to when you do a Django admin start. So just a few steps to get everything set up here Going to set up my database. And we have gotten some feedback that people would actually like a GUI around this as well, similar to what WordPress has when you you know know it kind of it asks you to set it up through kind of a wizard so that's something that would be nice. So this is just applying the Django migrations. And I'm going to create a super user so I can log in
Speaker 4: Yes. That's the greatest feature ever, by the way. Um and uh now that I have created a user, I'm just going to do uh Django run server. Okay. So that was kind of the normal the normal flow of of really starting any Django project. And if I come over to my server now You could see that I have just, you know, very bare bones. It named it Lightning after what I what I uh named it. But let's go ahead and log into the Wagtail admin that kind of replaces the Django admin. And let's get to work. So this looks
Speaker 4: this is pretty much exactly like stock Wagtail. I'm gonna go into my homepage here. And uh but before we do that, let's just go right into the settings. There's a lot of settings. We're going to upload our logo so we can get started right away. So I'll just load a logo in there. And you could do a favicon and stuff as well. I save that, gives you a nice branded experience so that you could use this, you know. Especially if you support multiple websites, it's easy to tell which one is which. Going back, you can see we now have our little logo in the corner. But the page is still empty. So let's fill out a few things on the home page Now in Wagtail, when you go to the homepage, you have to define everything you want, you know, every field, it's
Speaker 4: it's a Django model. You fill out whatever you want on your field, a title, a description, an image, etc. With Code Red CMS, we've kind of pre-populated a lot of basic stuff that basically every website needs. So I'm going to load in a hero unit. Which is just an image. And it's all based on bootstrap, so we have a everything is grid and column-based, and we can add all kinds of content. I'm just gonna add some text. Make that an H2, and I'll go ahead and preview my homepage. And now I've got a hero unit with some content in there.
Speaker 4: There. So you can follow this paradigm the whole way through and build your entire page out without having to do any code. And if you want to customize it, you can override a little bit of HTML and CSS. And uh you have a fully functioning Wagtail CMS without having to write any code at all. So thank you. Hopefully this is useful. Um check it out on GitHub.
Speaker 5: All right. An ecosystem is an interconnected system of independent parts. In a healthy ecosystem, consumers, producers, and resources in an environment interact in balance with each other. But an ecosystem can easily fall out of balance. If you remove a critical piece of a system or introduce a new participant, an ecosystem can collapse or find a new unhealthy equilibrium. Software is an ecosystem. Developers write new software. That software is consumed by users to solve problems. That use of software generates revenue, which funds the development of yet more software. However, the open source software ecosystem is not at present a healthy ecosystem, despite the fact that open source tools and libraries are critical to the health of an increasing number of businesses. Those who consume open source software do not generally contribute back to the ecosystem.
Speaker 5: They consume, but they don't necessarily contribute to the development and maintenance of what they consume. There are plenty of indicators of this imbalance. Critical pieces of infrastructure have been underfunded or undermaintained. Important research and development work either hasn't been done or hasn't been done in a timely fashion. contributor burnout is prevalent in open source communities. The problem has been well researched and documented, but that hasn't caused a significant change in business practices. Attempts to raise awareness of the problem have been met with antipathy. Attempts to force the issue have been met with hostility. So, how can we fix this problem? Well, naming a thing gives it power, and I'd like to suggest a way to name this problem. Carbon emissions are one of the largest contributors to climate change, and so one of the responses to climate change has been the emergence of the carbon neutrality movement.
Speaker 5: The term carbon neutral provides a rallying cry for those advocating for change. It provides an indication of the type of change that is required, and it provides a measurable and achievable goal. Businesses can indicate their commitment to addressing climate change by adopting a carbon neutrality pledge. Consumers can then use those pledges as part of their process of deciding which businesses to support. Why am I talking about carbon neutrality? Well, the software ecosystem is faced with a very similar problem. We need to balance the consumption of open source software with the need for maintenance reports. resources. We need software consumers to balance their consumption with open source contribution. We need the software ecosystem to become contributor neutral. Carbon neutrality doesn't mean we have to revert to living in a cave. It asks us to critically analyze and monitor our activity to ensure that the value we extract from the environment is met with an equal commitment to give back to that ecosystem.
Speaker 5: You can do that by changing your behavior, or you can do it by offsetting the activities that can't be minimized. Either way, the aim is to have a net zero impact on the environment. Being contributor neutral is much the same, but to the software ecosystem. It's a commitment to be aware of how much open source software you are using and the relationship that you have with the producers of that software. It means trying to be part of the contribution process if you can, but if you can't, it means offsetting your consumption by providing resources to those that are contributing. So, how do you become contributor neutral? Well, at the individual level, you can contribute to open source projects and you can donate to open source foundations or to individual maintainers But the more important activity isn't the individual contribution or donations. It's to change behavior.
Speaker 5: Talk about your pledge to be contributor neutral, about what you are doing to meet that pledge. Tell your suppliers that their contributor neutrality is a factor in your purchasing decisions. This isn't a new problem, but my hope is that by giving this problem a name. we can rally around that and actually generate change to embed decisions about open source maintenance in the C-suite of companies and with managers. not just amongst engineers on the ground, and to actually see businesses give this problem the same sort of consideration that they give their environmental impact. Here's one vision of a potential future. Imagine if when you signed up for your AWS or Azure or Google Cloud account, you could tick a box that says, I would like to offset my open source use. That would increase the price of your compute instance by some small amount, but those funds would be directed automatically to the PSF or the DSF or whatever other organization you nominate.
Speaker 5: Or when picking a SaaS vendor, you could check a similar box and the vendor would add a small charge to your monthly bill. Or better yet, not even give you the choice and just factor it into the actual cost of doing business because they are a contributor-neutral business. This would fundamentally change the conversation around open source funding. Rather than the PSF and the DSF begging for donations, the money needed to maintain Python and Django would be baked into the operational cost of people using those projects. If this idea resonates with you, I need your help. We need to get this message out there. We need resources to show people how to take action, tools to help people compute what their contributor offset should be, and content that the engineers can use to help convince their managers that their company should become contributor neutral. If you'd like to help out with this, please come find me and have a chat. Thank you very much.
Speaker 6: Thank you, Russell.
Speaker 7: All right, thank you. Uh so I'm gonna be talking about leveling up the uh ORM. Um that's my information at the bottom, my name. Um And the talk can be found on the GitHub page both as the HTML here and also as a markdown file, which is sometimes easier to grab code out of if you want to know about converting markdown to HTML. presentations you can ask me about that later. But right now we'll talk about leveling up the ORM. And what I mean is the ORM provides a lot of low-level tools that describe what kind of SQL it's going to generate. It also provides some high-level tools That describes the intentions of the code that you're writing. And as much as we can, we like to work in the high-level space. It often generates you wind up with more readable and more maintainable code. So I'm going to give you a couple examples of low-level things and a bunch of high-level stuff that's on top of that, and uh hopefully you'll be convinced that the high-level stuff is more readable, more maintainable.
Speaker 7: So let's start with uh Django 1. 8, where we get the introduction of case when. Uh case when is a low-level conditional expression. It's low-level because you write case when in Python, you get case when in the SQL. It's basically translated exactly. And what can you do with that? For example, if you have a book model and it's rated by your users, you can um Aggregate and count the number of one, two, three, four, five uh star ratings that your users have using case one like this. You count the case where the rating is five and uh etc. Whoops. Why did I go to the end? Um in Django two point oh, we get the filter keyword argument in aggregates. So instead of using case when, we can do the same thing by saying we're gonna count the user rating, but filter uh
Speaker 7: for a particular value. This is a higher level version of the same thing. So in instead of using case when we use this one, it's a bit more readable, more maintainable. Uh also it may or may not be implemented with case when on the back end, and in fact in some cases it's not. Um Django 2. 2 adds bulk update. So if you have a loop and you're saving each time through the loop, you've got a database query each time through the loop and you're going to have a performance issue with your latency to the database. So instead, you want to generate a single SQL query by putting your uh instances in a list and then calling Bulka update once on the list. This was introduced in Django 2. 2. Uh in in reality, it's built on top of Case When. So if you're not on Django 2. 2 yet, you can do a bulk update using CaseWen.
Speaker 7: This is the basic implementation of that. And I think It's pretty clear that the bulk update is much more readable and maintainable than uh generating all these when statements and and putting it in a in a case. Um but this is an example of the bulk update is a higher level abstraction built on top of the lower level building block of case when Third-party apps can also be built on top of the lower level things. Say you have your your book model. Books are many to many with authors and genres, and you want to ask a question like For each author, how many books in each genre has that author written? This abstraction has a name, this is a pivot table, and you can pip install Django Pivot. And then simply call the pivot function and get your pivot table, which is a lot simpler than writing a whole bunch of uh case when
Speaker 7: statements to try to pull that out individually. The higher level version is more readable, more maintainable. Um in Django 111 we got subqueries, and subqueries have a remarkable performance benefit. Um where where I work, we've had some queries that go from minutes to milliseconds by changing all of our aggregations to use subqueries instead of joins. Um and that's a humongous performance benefit for us. Um and in case uh You want more evidence of that? Here's a blog article that says basically the same thing. Using these subqueries can be a huge performance benefit. But just because it's possible doesn't mean it's easy. This is a ticket in the Django ticket tracking system that was added a couple months after the release of Django
Speaker 7: 111 that said basically, uh, can we make these subqueries do aggregations? Um in fact it was already possible when the ticket was entered. It's just not easy at all. So why is it not easy? Here's the uh The way to do a count of books for each author without subqueries, very simple code, easy to read. Here's how to do it with subqueries. So using the low-level abstraction is difficult. It's a lot of code, it's a lot of boilerplate, and I promise every single character in there is necessary to make it work right. We don't want to have to do that just to get the same thing we had before. So instead pip install Django SQL utils and then you can get the same thing this way. Now we're just expressing what we want. Our book count is a subquery count of books.
Speaker 7: And Koji, you can say it with me. It's more readable, it's more maintainable. It is more readable and more maintainable. There we go. That's it.
Speaker 8: To start, what do you call a grizzly bear with no teeth? A gummy bear. We can only go up from here. This is a brief presentation about the cognitive playbook, which was first researched by Dr. Robert Cadell. The goal is to introduce the framework which is based on the geometries of things. For outline transitions and featuring Ben Franklin quotes and pictures of murals from Philadelphia. My name is Jeremy Gaidens, and I'm an employee at the University of Penn, proudly representing Words, the award-winning research platform. I'm a Tom Petty fan who does web design, in that order. I have a wife, two sisters, and a cat named Arya, who is a princess. Lastly, I bleed Philadelphia
Speaker 8: Sixers Blue and will forever trust the process. On to the show. The best way to learn something, to truly grok it, is to teach others. This semester, I started going back to school to complete my master's degree at the University of Penn. I'm taking course 642, a cognitive playbook. A cognitive playbook enables students to understand three fundamental perspectives in business: strategy creation, organizational design, and critical thinking To understand these perspectives, we are introduced to cognitive plays, the aforementioned geometries of things. At its core, there are four cognitive plays: point, linear, angular, and triangular.
Speaker 8: Point of this talk is to introduce these cognitive plays as they help simplify complex problems. Each cognitive play has its time and place. The next section will look at each one in detail. Point thinking. Point thinking is black or white. It is useful for establishing essentials and demonstrating contrast. In strategy creation, it is key to defining a business persona. An example is establishing an organization identity. Who we are and what we do. Sample question: What is the difference between good and bad organizational politics? Linear thinking. Linear thinking is shades of gray. It is useful for providing yardsticks and reaching simple compromise.
Speaker 8: In strategy creation, this is key to measuring performance. If it isn't measured, it isn't valued. An example is at your job, how much time is allocated to fire fighting versus fire prevention Sample question. What are the most important criteria in assessing the quality of management? And why? Great. Angular thinking. Angular thinking is black and white. It is useful for making sense of issues that reduce to two variables but cannot be decompressed into point /slash linear frame. In strategy creation, this looks at what perplexes us. An example is the classic two by two matrix. In this case, the x-axis is me winning, and the y-axis is kojo winning. Ideally, we want to land in a northeast quadrant where we both win.
Speaker 8: Sample question. How can a large organization exhibit the flexibility of a small organization? Triangular thinking. Triangular thinking is thinking in color. It is useful for structuring complex problems that span strategy, technology, and organization. In strategy creation, it looks at how we compete, organize, and grow. An example is Jack and Jill. There are only three archal type ways that they can constructively interact Jack and Joe can one, each do their own thing and have minimal contact. Autonomy. In sports, this is baseball Number two, settle on a boss slash subordinate arrangement. Control. In sports, this is football. Number three, collaborate as peers.
Speaker 8: Cooperate. In sports, this is basketball. Sample question. Technology can be used for any mix of the three reasons. To increase individual capabilities, autonomy, to increase collective capabilities, cooperation. To decrease cost control. How does your organization balance these uses? How should it? The importance of grasping patterns of thinking, i. e. the cognitive plays, has become increasingly critical. This approach allows you to decide this allow this approach allows you to decode uh complexity by isolating form. As aforementioned, each cognitive play has its time and place. The challenge is to mix and match appropriately. The purpose of this talk is to help simplify problems. By understanding these cognitive strategies, you'll be able to develop well-balanced solutions to the complex problems in your life.
Speaker 8: Bring it home. Here is my contact info. Thanks for your time. Please let me know if you have any questions, comments, or concerns. Here's my contact info. Let me know if you want to talk Sixers, Django, Disc golf, or Yoga. Thanks again for listening and a big thank you to the DjangoCon organizers. Take care and have a good day. Lastly, too long didn't read. Use triangular thinking to solve complex problems.
Speaker 6: Well done. Well done. Uh so my name's Dane.
Speaker 8: I'm a lead web application developer at Ithaca, and we make JSTOR. org. And if you were at my talk yesterday, you know that JSTOR uses a ton of microservices. uh on the back end and then we uh uh interact with all those services in python.
Speaker 7: And so we had a bunch of code that looked like this.
Speaker 6: So we use requests
Speaker 7: and we need to do service location to figure out what hosts that service lives at so that we can call one of them. Uh and then we keep the name of that service as well as some of the endpoints that we're interested in and what kinds of parameters that endpoint takes and things.
Speaker 6: And then uh we would have these methods that would uh sort of put all that information together, format in the information uh being requested through the through the workflow uh and then ultimately call that endpoint and get the data. And then we had a lot of them that looked pretty similar. So this one does the same thing for a different service at a different endpoint. And these were kind of scattered throughout our code. Um and it was a lot. So we centralized some of that by trying to make some centralized configuration for all of those service names and endpoints and different ways of calling these things. Uh but ultimately that didn't help a lot either. It really just fixed this part of the code and we still had a lot to deal with. And we really wanted to
Speaker 6: um be able to do something a little more SDK-like. So if you imagine some of the some of the popular APIs that provide an SDK, we wanted that kind of experience for all of our services, but we didn't want to build an SDK for all of our services. So we wanted something SDK-like and it needed to support streaming and service location and timeout specs and stub data and a bunch of other things. So we built something. that I'm going to show you. And I'm going to use the Pokemon API because it's pretty cool. If you haven't looked at it before, you should check it out. And what we're going to do is build a little uh client for this endpoint to look at Pokemon data. So
Speaker 6: I'm going to make a virtual environment And I'm going to install APIon. And then I'm going to import uh the service class because we're interacting with a service and it has a JSON endpoint. And so we're gonna call this Pokey API, and that is a service. And it has some domain, which is PokAPI dot co. Let me make sure that's right. Yep. And then it's got this endpoint.
Speaker 6: Returns JSON and its path is API V two Pokemon. And that Pokemon has a name. Oh , need a quote. There we go. Well, you've got to redefine the class. With a quote. Okay. So then uh we want to get some data for a Pokemon, so we're just gonna call pokeapi. uh endpoint should have named that Pokemon and then the name is Ditto and we get that data back
Speaker 6: And then uh if we want to maybe look at the sprite for the ditto uh that lives in sprites. And then there's like a front default sprite. So we can get that and go look at what Ditto looks like. There he is. All its glory. And then if you want uh you know any any other Pokemon, you can just change the name you want. We'll look at Doug Trio. There's that one. Um and so the the thing is basically requests under the hood, but gives you this kind of SDK-like experience and you can specify which parameters are required for a particular endpoint, what the default values can be for that.
Speaker 6: You can change the default method to use so you don't have to always specify method equals post or do. uh request dot post so you get this very sort of native Pythonic experience. Um so it's on GitHub, uh it's on read the docs. So we're not sprinting on this, but we've had a couple people here contribute to it before, and we'd love you to use it and tell us how we can make it better. Thanks.
Speaker 4: Alright, so by all the shares, like I guess we're all like pretty hungry.
Speaker 3: Try to speed through this. Oh, thank you. Uh So I work for a company uh called Fifteen Five. We do employee feedback software and we use Django, as you can probably guess. And
Speaker 8: Django Admin is great, I love it, but uh unfortunately when your product is really good, 50 fifty-five. Um it uh you got a lot of customers, that means like millions of rows in your tables and uh searches can be really, really, really slow. Um so what if there was a library you could easily put into your application that would speed up your searches and uh make the searches better? And there is. That's why I'm here. It's called Django QL. Uh you can look it up and it's uh there's some pretty good documentation on it. There's a video, which I'm not gonna show you, and uh you can extend it. Um Um it's really easy to add in. I did it like in a single day. This like is a really simple commit that's like half the work
Speaker 8: right there. Um you just import Django QL search mix in and create your Ridiculously simple class, couldn't be simpler, and you add it in. That's it. Uh what does this look like? Well, there's a little checkbox right here to the left. You click on that, and then you can search based on specific fields or tables. So for example, I can search search uh info and then look on the info table, get the uh companies with the current size of have all these Boolean operators greater than less equal to in a one. uh greater than a thousand so because I'm searching on a specific field it's uh very fast versus like let's say if you have multiple fields configured, that could be pretty slow doing a general search.
Speaker 8: Um I can see that the uh RBQMJB company is pretty popular. They're one of the larger companies. I'm sure you've heard of them. Make uh all the food bars in the world. And
Speaker 3: yeah, if you uh look in the issues for performance, you can see like I have a comment here. Um For couple tables with a million rows, it can like greatly speed up performance. And for 100,000 rows, you also see some performance benefit.
Speaker 8: But
Speaker 3: of course, it depends on uh your exact environment and configuration.
Speaker 8: So yeah, Django QL, look it up, use it, really simple to add. I like it. And I think we're all hungry, so I'm gonna end the talk here.
Track user behavior such as screen grabs with a Django endpoint, then inject a unique identifier into each suspected user's data. If that identifier appears in shared content, it can be traced back to the account and the pirate can be contacted.
Discussed at 1:54Use Django's `StaticLiveServerTestCase`, whose `self.selenium` object exposes Selenium's Python bindings for finding elements, entering keys, and clicking controls. Page objects and locator classes can further organize the browser interactions and selectors.
Discussed at 6:14Run Selenium Hub with local browser containers such as Chrome and Firefox, or use a hosted service such as BrowserStack to provide remote browsers and recordings of the test runs.
Discussed at 7:46Describe scenarios with Given/When/Then syntax, then connect those steps to Selenium implementations using Behave and Behave-Django. HipTest can provide a UI for creating scenarios and generating reusable step stubs.
Discussed at 8:33A normal property recalculates whenever it is accessed, while a cached property computes its value once per object instance and reuses it. Deleting the cached attribute forces it to compute again.
Discussed at 11:11Define expensive fixtures such as related model objects as cached properties so they are created only by tests that actually access them. This avoids unnecessary database queries in shared test setup.
Discussed at 12:44CodeRed CMS is a Wagtail-based CMS distribution aimed at informational and marketing sites, with common content features prebuilt so a site can be created without writing code. It provides a WordPress-like starting experience while retaining Wagtail and Django customization.
Discussed at 16:02Install the package, run its project-start command, apply migrations, create a superuser, and start Django's development server. From the Wagtail admin, you can brand the site and build pages using predefined content blocks such as hero units.
Discussed at 16:47Contributor neutrality means balancing the open source software a company consumes with an equivalent commitment of maintenance resources, contributions, or funding. Companies can contribute directly, donate to foundations or maintainers, and make the pledge part of purchasing and supplier decisions.
Discussed at 22:05They can fund maintainers or organizations such as the Python and Django foundations, either directly or through an added charge from cloud and SaaS providers. The talk proposes building those contributions into the operational cost of using open source software.
Discussed at 22:56Higher-level ORM features express intent more directly, making code more readable and maintainable than manually constructing lower-level SQL expressions. Examples include filtered aggregates and bulk updates built on lower-level primitives such as `Case` and `When`.
Discussed at 26:03Instead of saving objects one at a time and issuing a query for each object, collect them and call `bulk_update` once to generate a single SQL operation. This reduces database round trips and latency.
Discussed at 27:03The `django-sql-utils` package provides higher-level helpers, such as a subquery count, so you can express the desired aggregation without writing the substantial boilerplate required by the lower-level ORM API.
Discussed at 29:22They are point, linear, angular, and triangular thinking. Point thinking establishes binary essentials, linear thinking measures along a scale, angular thinking handles two-variable tradeoffs, and triangular thinking structures complex problems involving multiple dimensions.
Discussed at 31:10It structures problems across strategy, technology, and organization, including how people or teams compete, organize, and grow. The talk recommends it for complex situations that cannot be reduced to a simple yes/no choice or a single scale.
Discussed at 33:30The demonstrated APIon library lets you define a service, its domain, JSON endpoints, paths, parameters, defaults, and methods declaratively. The resulting client uses a Pythonic interface while handling requests, service details, and endpoint data under the hood.
Discussed at 36:57Add the DjangoQL search mixin to the admin and let users search specific fields or tables with operators such as greater-than and less-than. Field-specific searches avoid the slowness of broad searches across many configured fields.
Discussed at 40:50Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.
Published October 20, 2021
Published October 25, 2019
Published November 8, 2018
Published November 3, 2022
Published September 30, 2020
Published October 25, 2019
Published September 7, 2017
Published October 23, 2025
Published December 6, 2024
Published November 22, 2023
Published November 8, 2018
Published October 23, 2025
Published December 6, 2024
Published June 13, 2025
Published December 6, 2024
Published July 19, 2024
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 15, 2026
Published July 14, 2026