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

Django. support django orm autocompletion

Open inkoff opened this issue 1 year ago • 14 comments

In pycharm or using the following instruction: described here, - the user can use code completion based on the "related name" value of the model's "foreign key" relasionships.

Can you add this to Pylance, at now this do not work.

inkoff avatar Dec 02 '22 16:12 inkoff

That would be awesome!

diego351 avatar Dec 02 '22 17:12 diego351

Do you have an example? This seems to work for me:

from __future__ import annotations
from django.db import models

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from django.db.models import Manager

class Article(models.Model):
    tags: Manager["Tag"]

# Declare the ForeignKey with related_name
class Tag(models.Model):
    article = models.ForeignKey(
        Article,
        on_delete=models.CASCADE,
        related_name="tags"
    )
    name = models.CharField(max_length=255)

# Return all tags
Article.tags.all

image

At least that's what the django issue described as the solution. We do already ship the django_stubs, so it should pick those up automatically.

rchiodo avatar Dec 02 '22 17:12 rchiodo

Gents, there's more that I think can be done.

class Transmission(models.Model):
    stations = models.ManyToManyField("Station", through="StationTransmission")
    sport = models.ForeignKey("Sport", on_delete=models.PROTECT, null=True, related_name="transmissions")
    at = models.DateTimeField(db_index=True, null=False)

class Sport(models.Model):
    type = models.TextField(choices=SportType.choices(), db_index=True, default=None)

class StationTransmission(BaseMixin):
    transmission = models.ForeignKey("Transmission", related_name="station_transmissions", on_delete=models.CASCADE)
    station = models.ForeignKey("Station", on_delete=models.PROTECT)

class Station(BaseMixin):
    name = models.TextField()

Field filtering, note type specific completions:

image

Filtering by foreign_key fields:

image

Filtering by related_name:

image

Double underscore is django orm thing. Having this kind of competition would be luxurious.

diego351 avatar Dec 02 '22 17:12 diego351

Thanks @diego351. Are your screenshots from Pycharm?

rchiodo avatar Dec 02 '22 18:12 rchiodo

@rchiodo yes. The best django integration out there so far I think. I made a switch from pycharm so would like to help to surpass it :)

diego351 avatar Dec 02 '22 18:12 diego351

У вас есть пример? Кажется, это работает для меня:

from __future__ import annotations
from django.db import models

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from django.db.models import Manager

class Article(models.Model):
    tags: Manager["Tag"]

# Declare the ForeignKey with related_name
class Tag(models.Model):
    article = models.ForeignKey(
        Article,
        on_delete=models.CASCADE,
        related_name="tags"
    )
    name = models.CharField(max_length=255)

# Return all tags
Article.tags.all

изображение

По крайней мере, это то, что проблема django описана как решение. Мы уже отправляем django_stubs, так что они должны автоматически загружаться.

Do you have an example? This seems to work for me:

from __future__ import annotations
from django.db import models

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from django.db.models import Manager

class Article(models.Model):
    tags: Manager["Tag"]

# Declare the ForeignKey with related_name
class Tag(models.Model):
    article = models.ForeignKey(
        Article,
        on_delete=models.CASCADE,
        related_name="tags"
    )
    name = models.CharField(max_length=255)

# Return all tags
Article.tags.all

image

At least that's what the django issue described as the solution. We do already ship the django_stubs, so it should pick those up automatically.

If you do not use an additional parameter declaration wrapped in a manager in the class, then there is no access to the auto-completion of the related_name field

inkoff avatar Dec 02 '22 19:12 inkoff

Can you give a concrete example? Do you mean this class does not have the 'Manager' type on it?

class Article(models.Model):
    tags: Manager["Tag"]

rchiodo avatar Dec 02 '22 19:12 rchiodo

If I don't create "tag: Manager["Tag"]" , I won't have access to the "related_name="tags"" field elsewhere in the code for autocompletion. Unlike pycharm. The author of the "crutch" writes about this on the forum 'django'.

inkoff avatar Dec 02 '22 19:12 inkoff

Do you have a link to the forum post? I'd love to read what they're talking about. Not having much luck searching for it.

rchiodo avatar Dec 02 '22 19:12 rchiodo

Do you have a link to the forum post? I'd love to read what they're talking about. Not having much luck searching for it.

https://django.fun/en/qa/418209/

inkoff avatar Dec 02 '22 19:12 inkoff

class Transmission(models.Model):
    stations = models.ManyToManyField("Station", through="StationTransmission")
    sport = models.ForeignKey("Sport", on_delete=models.PROTECT, null=True, related_name="transmissions")
    at = models.DateTimeField(db_index=True, null=False)

class Sport(models.Model):
    type = models.TextField(choices=SportType.choices(), db_index=True, default=None)

class StationTransmission(BaseMixin):
    transmission = models.ForeignKey("Transmission", related_name="station_transmissions", on_delete=models.CASCADE)
    station = models.ForeignKey("Station", on_delete=models.PROTECT)

class Station(BaseMixin):
    name = models.TextField()

.prefetch_related() and .select_related() completions

image image

Please note ForeignKey reference by string, defined in the same file but further on.

diego351 avatar Dec 03 '22 12:12 diego351

@rchiodo Hi there. Can I ask if there's any progress on this? Also, changing name of this issue to "support django orm autocompletion" might be good idea. Thanks!

diego351 avatar May 04 '24 10:05 diego351

Thanks for the feedback. Unfortunately, this is still pretty far down the priority list. We've been discussing some things related to this: https://viicos.github.io/posts/an-alternative-to-the-django-mypy-plugin/, but haven't implemented anything yet.

rchiodo avatar May 06 '24 15:05 rchiodo

we could do similar thing we did for pytest completion (transforming original text to contains extra type annotation behind the scene) but unlike pytest completion, we would need to do that for workspace wide not just 1 document, since source of the trigger (where related_tag is added) and destination of the effect (where completion is shown) are different.

heejaechang avatar May 06 '24 17:05 heejaechang