pylance-release icon indicating copy to clipboard operation
pylance-release copied to clipboard

Provide improved support for django

Open rchiodo opened this issue 2 years ago • 42 comments

MVP idea:

  • Completion for all related keys generated and or specified #3704 (maybe through dataclass_transform)
  • Extended completions for filterby etc based on key names generated by Django https://github.com/microsoft/pylance-release/issues/3704#issuecomment-1335592027
  • Goto definition on models referenced in Settings.py #3700
  • Completions on models referenced in Settings.py #3700

MVP Python Core?

  • Manage.py shortcuts (especially so you could map them to keyboard shortcuts)

rchiodo avatar Dec 01 '22 20:12 rchiodo

  1. Ability to run task of the manage.py utility
  2. Ability to goto definition models referenced by string by'<app_name>.<model_name>'when model sits in '<app_name>.models.<model_name>'

diego351 avatar Dec 01 '22 20:12 diego351

Manage.py could

  • have tasks.json added for each operation
  • have commands for each operation
  • have more specialized commands for different operations (like manage.py runserver should be on the 'run' tab)

All of these are probably better suited for the core python extension though. Not really language server related. See this documentation: https://code.visualstudio.com/docs/python/tutorial-django#_create-a-debugger-launch-profile

Which could be improved, but probably better to do that in the python extension.

rchiodo avatar Dec 01 '22 21:12 rchiodo

Views.py

  • Auto fill in types for any function that has a request parameter
def index(request):
   pass

becomes

def index(request: HttpRequest) -> HttpResponse:
   pass

automatically (line completions maybe?)

rchiodo avatar Dec 01 '22 22:12 rchiodo

Urls.py

  • Auto line complete all of the exported views from views.py (and compute their path?)

rchiodo avatar Dec 01 '22 22:12 rchiodo

https://github.com/microsoft/pylance-release/issues/3704

rchiodo avatar Dec 02 '22 17:12 rchiodo

Fields with required values should flag an error if those values are missing. Example:

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField()
    votes = models.IntegerField(default=0)

choice_text is missing max_length

rchiodo avatar Dec 03 '22 00:12 rchiodo

What @diego351 said in this issue: #3700

Settings.py basically takes a list of modules. It would be nice if they could be treated that way when entering them.

Like by doing

  • Autocompletion on them
  • Goto def on them

rchiodo avatar Dec 03 '22 00:12 rchiodo

Could completions for models be driven by the data in the 'migrations' folder?

rchiodo avatar Dec 03 '22 00:12 rchiodo

@rchiodo It's actually interesting how Jetbrains inferes that. Might do some tests.

btw, @rchiodo do you get notifications for closed issues?

diego351 avatar Dec 03 '22 01:12 diego351

btw, @rchiodo do you get notifications for closed issues?

Only if I had already responded to the item or you mention me by github id.

Is there another item we already closed that's about this topic?

rchiodo avatar Dec 05 '22 17:12 rchiodo

@rchiodo Not about that topic, but don't know how to contact you another way, didn't wanted to create duplicate ticket https://github.com/microsoft/pylance-release/issues/3678

diego351 avatar Dec 05 '22 17:12 diego351

  "python.analysis.packageIndexDepths": [
    {
      "name": "django",
      "depth": 3,
      "includeAllSymbols": true
    },
    {
      "name": "rest_framework",
      "depth": 3,
      "includeAllSymbols": true
    }
]

Just this regular django setup hits Workspace indexing has hit its upper limit: 2000 files. In production it's much more needed. We need https://github.com/microsoft/pylance-release/discussions/2608 to make vscode competitive django IDE.

diego351 avatar Dec 05 '22 19:12 diego351

Created an issue to think about whether dataclass_transform can help with Django models: https://github.com/microsoft/pylance-release/issues/3720

debonte avatar Dec 05 '22 23:12 debonte

Some ideas from the work done here: https://youtu.be/Lz4I7rFmFdY?t=1233

Generate type stubs on the fly for django classes

rchiodo avatar Dec 08 '22 17:12 rchiodo

At this point in the video you can see the presenter use what @diego351 talked about in #3704

rchiodo avatar Dec 08 '22 18:12 rchiodo

Comment here makes it seem like Django functions have data automatically sent to them (like pytest fixtures): https://github.com/microsoft/pylance-release/discussions/3187#discussioncomment-3421854

Type inference would be specific to Django I'd think. Much like pytest fixtures. Needs more investigation to see how this works.

rchiodo avatar Jan 06 '23 18:01 rchiodo

https://github.com/microsoft/pylance-release/issues/3704#issuecomment-1335592027

Looking here: https://reinout.vanrees.org/weblog/2015/06/03/05-lookups-transforms-expressions.html

Shows that Django completions for parameter names can include a LOT of stuff. It would be cool to include at least some of these (if not all) in completions for parameters. (much like Pycharm does)

rchiodo avatar Jan 09 '23 22:01 rchiodo

An example of why the 'generated' keys are useful.

Suppose we have these two models (from the Django tutorial):

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

   

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

Both of these objects have hidden (generated) fields.

  • Both have an id
  • Question has a 'choice_set' generated by the ForeignKey relationship
  • Both have a primary key called 'pk' which by default maps to 'id', but can be overridden

Example usage:

q = Question.objects.get(pk=1)
q.choice_set.create(choice_text='Not Much', votes=0)

In this example, pylance would have to know

  • The implicit fields
  • The types of those fields
  • The implicit arguments for methods on those fields

rchiodo avatar Jan 09 '23 22:01 rchiodo

Another idea: Query pattern matching.

Urls might have something like so:

urlpatterns = [
    path("", views.index, name="index"),
    path("<int:question_id>/", views.detail, name='detail'),
    path("<int:question_id>/results", views.results, name='results'),
    path("<int:question_id>/vote", views.vote, name='vote'),
]

See here for more information: https://docs.djangoproject.com/en/4.1/topics/i18n/translation/#translating-url-patterns

It might be possible to have a general regular expression support? Doesn't seem to be asked for, but maybe as a separate extension. Patterned after what regex101.com does.

rchiodo avatar Jan 09 '23 23:01 rchiodo

Another obvious example, intellisense in Django templates. This would likely require an entirely different parser.

Yeah definitely. Django's template language is not python.

Example, this is how you concat two strings:

{{ str_1|add:str2 }}

rchiodo avatar Jan 10 '23 00:01 rchiodo

There are predefined globals that can be set that have special meaning.

It would be nice if they:

  • Came up in completions
  • Had type information

Example - a Urls.py:

from django.urls import path
from . import views

app_name = 'polls'

urlpatterns = [
    path("", views.index, name="index"),
    path("<int:question_id>/", views.detail, name='detail'),
    path("<int:question_id>/results", views.results, name='results'),
    path("<int:question_id>/vote", views.vote, name='vote'),
]

app_name and urlpatterns are globals that django looks for.

https://docs.djangoproject.com/en/4.1/topics/http/urls/#how-django-processes-a-request

rchiodo avatar Jan 10 '23 19:01 rchiodo

Warning in forms that don't use the csrf_token tag

rchiodo avatar Jan 10 '23 21:01 rchiodo

@diego351, @luabud pointed this extension out to me:

https://marketplace.visualstudio.com/items?itemName=tonybaloney.python-task-provider

That provides commands for manage.py. Thought that might be useful for you.

rchiodo avatar Jan 25 '23 17:01 rchiodo

Thanks! How the initial support is going? Please let me know if you need anything django related

diego351 avatar Jan 26 '23 07:01 diego351

@diego351 Honestly, we're still in the investigation phase, trying to figure out what to do first. Any more suggestions of things that you'd like to see or any other features you've seen elsewhere would be a big help. Thanks for asking.

rchiodo avatar Jan 26 '23 17:01 rchiodo

Another idea: https://github.com/microsoft/pylance-release/issues/3874#issuecomment-1405665334

Supporting other languages inside of strings. Might also how we implement DTL support. Ship a separate language server just for the DTL parts.

rchiodo avatar Jan 27 '23 17:01 rchiodo

@rchiodo Perhaps off-topic, but intellisense for the django.conf.settings object, which includes user settings.py variables would also be phenomenal.

dakotahorstman avatar Mar 23 '23 17:03 dakotahorstman

  1. Ability to run task of the manage.py utility
  2. Ability to goto definition models referenced by string by'<app_name>.<model_name>'when model sits in '<app_name>.models.<model_name>'

@dakotahorstman do you mean like option 2 that @diego351 mentioned?

rchiodo avatar Mar 23 '23 17:03 rchiodo

Albeit, I split my settings.py out into multiple settings/*.py files depending on which mode my server is running in. For example: settings/base.py, settings/dev.py, settings/prod.py, settings/test.py if that makes much of a difference.

dakotahorstman avatar Mar 23 '23 17:03 dakotahorstman

@rchiodo I mean all settings, not just model definitions. Like regular intellisense, if I were to type settings., it would suggest DEBUG, INSTALLED_APPS, DATABASES, etc.

dakotahorstman avatar Mar 23 '23 17:03 dakotahorstman