PyCharm and Django
PyCharm had Django support from version 1.0. Over this time, the Django support has been gone through many changes, as well as many maintainers.
In this episode of Early Access PyCharm, I talked to both Ilya (the previous maintainer of the Django support for PyCharm) as well as Aleksei (the current maintainer). Ilya currently works on WSL and SSH (as well as other remote interpreters and targets) and Aleksei is also hard at work on integrating PyPI info into development and package management inside PyCharm.
We talk about how Django support came to be, as well as the challenges with creating tooling that works for Django. The main issue here that we’ve had to contend with over the years is Django’s dynamic nature, as well as the way it handles settings (mostly inside strings).
We then talk about code completion, especially about getting better code completion for Django’s ORM models. This has been challenging, since there are many dynamically created attributes that go into the class body as well as the
Lastly, we talk about what we plan to work on in the future for Django, and how we plan to make things easier to navigate with a project that is called "locations" for now.
Nafiul: [00:00:00] Hey everybody. Welcome to Early Access PyCharm. I’m your host Nafiul Islam. Today we’re going to be talking to Ilya and Aleksei, the two people behind the bulk of the Django support that you see in PyCharm. Now you’ve already met Ilya and Aleksei from previous podcast episodes. But I wanted them together in this one, just to talk about how Django support came to be and what we plan to do in the future. So without much further ado, Ilya, take it away. Tell us how this all started.
[00:00:29] Ilya: [00:00:29] Actually it started long before me by different people, but Django is one of the most popular frameworks and it was most popular 10 years ago also. So we decided that for those who use Python for web development we’ll need Django.
[00:00:48]Nafiul: [00:00:48] Okay. So I understand Django was really popular back then, but what other frameworks were you considering?
[00:00:55]Ilya: I believe it was, Pyramid, Web2Py, something like that. And there was also a framework named Zope, I believe, but it was very long time ago.
[00:01:08]Nafiul: Okay, so you decided to support Django. It’s a different thing to just supporting libraries. How did you go about doing that in the beginning?
[00:01:18]Ilya: Yes. I believe the first thing we decided to do was sophisticated code completion because PyCharm had code completion for Python itself, but it is not enough for Django, because Django has a very dynamic nature. Things like ORMs, for example, are a good example of dynamic nature when, for example, function argument names depends on module field names.
[00:01:45]Nafiul: So, Aleksei, talk to me about this a little bit more. We’re saying that the ORMs are a good example of Django’s dynamic nature, but for me, what I understand from an ORM is that you strictly define your models and you’re supposed to know what attributes are on those models.
[00:02:05]Aleksei: You know the Paul’s tutorial from the Django documentation. And, there’s a question and a choice and, every question has choices and it’s actually expressed in the model code as a choice, having a foreign key on a question, but it’s actually possible to get the choice set from the question object by calling the choice set method and it’s something you cannot really express statically. You can only do this once you evaluated all the models, built all the relationships and figured out that if this has this relation and this name, so the other, the question has to have attribute with this name. So it’s a very dynamic thing in nature.
[00:02:52]Ilya: One thing that also affected by those relations is the name of arguments of ORM methods, like filter method, it’s argument name so it depends on those relations.
[00:03:04] Aleksei: Yeah, exactly.
[00:03:05]Nafiul: So I’m guessing it’s not just dynamic attributes that you need to care about. You also need to care about the different methods that are available to you on different objects and their instances. So for example, filter is not just any filter. It has specific keyword arguments like attributes underscore lte or gte that allows you to filter on different attributes of the model inside of a filter method.
[00:03:31] Aleksei: Yeah. We have to have some knowledge of the exact methods that are being called. For example, it would make sense to code complete specific module attribute name in just any context. So we have to know that this for example is a filter function that is specific to Django. So knowing this, we can provide the useful suggestions.
[00:03:55]Nafiul: So Django in my opinion is not, and by this I mean Django support, is not just about code completion on methods and views, but it’s also about having support for manage.py, being able to connect a URL to a view, which is then connected to a model, if you have a model and which is then connected to a form, if you have a form. And being able to seamlessly navigate between all those different places in PyCharm, especially with the gutter icons and the go to definitions of declarations and all that. How do you do all of that? How does that actually work?
[00:04:30] Aleksei: Well, by understanding your code basically. So we know that a specific place has to, for example, a specific function has to have a name of the template in it. So knowing that we will also know which parameter is a pass to the template.
[00:04:50] We can code-complete there. We can have navigation back and forth to the template and from. So yeah, kinda like that by having more understanding of your code.
[00:05:02]Nafiul: So I’m guessing when you say "understand your code", is it that you have to write a lot of specific Django related logic to actually make this work? So I’m guessing that it’s a lot of custom code and it’s a lot of work.
[00:05:18]Ilya: Yes, probably, there are a lot of work, when you have to, just read Django manual and do some hard code. But we also have a special code that tries to understand parts of Python code that’s used to pass arguments to the template, like you can, pass arguments as a dictionary to the template, or you can use several dictionaries and merge them using update methods and so on. And we also need to understand it.
[00:05:44]Aleksei: Yeah. So part of this is the Python support: we, at least we know what Django library has inside. So that’s Python support. When this is not enough, we come with a knowledge of Django and try to implement the Django specific things. So it’s, sometimes it’s a lot of work, but it’s also built on top of many cool things like the Python support and the IntelliJ platform itself.
[00:06:15]Nafiul: So by now, you know, Django support is already pretty great. Uh, there’s navigation, there’s code completion. There’s, you know, sweet, sweet understanding of your Python code and your Django code. Are you running out of ideas, Aleksei?
[00:06:32]Aleksei: Well there is there’s always something to do. I mean sometimes the ideas come from other places. Sometimes we just have some new, cool stuff in Django, and we want to implement that.
[00:06:47]Nafiul: So I’m going to have to ask this because I have to, but like, what’s next for Django? Can you give us a sneak peek?
[00:06:54]Ilya: Since Aleksei does most Django support now, I think Aleksei should answer, he should have more ideas than me.
[00:07:02]Nafiul: Yeah, Aleksei, you should definitely have more ideas. And thanks, Ilya, for throwing him under the bus so that I didn’t have to.
[00:07:43]Nafiul: So let me see if I understand this. So you can already link between all the different parts of Django. So from URL to view, to template the model to whatever. And now what you’re trying to do is also link any URL. That’s an actual HTTP URL, directly to a view. And you know, this is, this is kind of something that’s already present in the end points project in IntelliJ, but we’re trying to bring that here and trying to support it for Django and PyCharm.
[00:08:17] Aleksei: Yeah, exactly.
[00:08:18]Nafiul: Okay. Tell me a little bit about how you want to make documentation better in Django, because you already have a lot of things enabled in Django?
[00:08:26]Aleksei: Well, I just want to make sure that it’s easy to access from inside PyCharm so that you don’t have to switch to your browser, go to the website and search for the class that you want to read documentation on. We could show you on the spot right there, right at the element. We already have some of this functionality, like if you have this enabled, we can show you documentation for your settings.py constants right inside PyCharm, which is pretty cool because from Python point of view, those are just variables.
[00:08:53]Nafiul: It’s so cool to hear how, you know, we’re constantly thinking about making Django easier to develop in PyCharm, but my question is, you know, how is it like to develop this kind of support on the IntelliJ platform and, how has it changed over time? Like, what was it like in the beginning and what is it like now?
[00:09:13]Ilya: I think the one thing that improved as a platform documentation: we now have official guides for plugin developers. Much less documentation was available seven years ago.
[00:09:27]Nafiul: Right. And the reason you say "plugin" is because everything that PyCharm and Django is actually sort of developed as a plugin on top of core IntelliJ functionality.
[00:09:38] Ilya: Yes. So seven years ago I had to, read a lot of platform internal code to understand how it worked and how to use it. And now you can just read documentation. I believe it’s one of the big difference. And we also have a much better remote development support that we used to have. So when you want to develop your young project on the remote server, using SSH, it is much easier to do nowadays versus many years ago.
[00:10:13]Nafiul: Well, on that note thank you so much both of you for joining me today. And I hope to see you again pretty soon.
[00:10:20] Aleksei: Thanks.