Django: Приведите связанное поле к типу QuerySet
Основываясь на официальной документации:
# 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-pylint) не в состоянии напечатать его правильно: Article.tags is Any
, я ожидал QuerySet[Tag]
.
Могу ли я объявить ссылку Article.tags
в классе Article
? (предпочтительный подход)
from django.db.models.query import QuerySet
class Article(models.Model):
...
# Related field declaration
tags: QuerySet[Tag]
Article.tags.all()
Или, может быть, мне нужно конвертировать его каждый раз, когда он мне нужен?
tags_qs: QuerySet[Tag] = Article.tags
tags_qs.all()
В обоих сценариях это выглядит тяжелым для реализации для каждой связанной области.
Конечно, это скорее вопрос для удобства разработки, чем критическая проблема.
Цель состоит в том, чтобы позволить моему линтеру и другим инструментам автозаполнения/распознавания разрешать связанные поля как тип QuerySet[T]
. Возможно, я не могу этого сделать из-за дизайна реализации Python, что больше похоже на проблему Django.
Есть ли другая альтернатива для решения этой проблемы?
Благодаря @Anentropic за указание правильного пути, я выбрал django-types. Эта библиотека легко интегрируется с VS Code и расширением PyLance (которое использует проверку типов PyRight, а не MyPY).
Установка с помощью VS Code
- Clone django-types
- Переименуйте
django_stubs
вdjango
.
- Переместите его в
./typings/django
в папку проекта
Адаптация
Следуя этим инструкциям: https://github.com/sbdchd/django-types#usage
from __future__ import annotations # or just be in python 3.11
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()
Теперь PyLance работает нормально с автозаполнением!