What type hint to use for a function which returns a queryset like the one below?
def _get_cars_for_validation(filter_: dict) -> QuerySet:
return (
Car.objects.filter(**filter_)
.values("id", "brand", "engine")
.order_by("id")
)
mypy
returns an error
Incompatible return value type (got "ValuesQuerySet[Car, TypedDict({'id': int, 'brand': str, 'engine': str})]", expected "QuerySet[Any]")
I would use ValuesQuerySet
but it was removed in Django 1.9. ValuesQuerySet
reported by mypy
comes from 3rd party lib django-stubs
(and I am unable to import it; is it actually possible?).
What is Django? Django is a high-level Python web framework that enables rapid development of secure and maintainable websites. Built by experienced developers, Django takes care of much of the hassle of web development, so you can focus on writing your app without needing to reinvent the wheel.
Python and Django are intertwined but not the same. Python is a programming language that's used for many different applications: artificial intelligence, machine learning, desktop apps, etc. On the other hand, Django is a Python framework for full-stack web application development and server development.
Django and Ruby on Rails — two of the leading backend web development frameworks and both open source — have been on the scene since the mid-2000s. They're no longer the trendy young bucks in web development, but they are still the seventh and 11th most-loved web frameworks respectively.
The name Django is boy's name of Romani origin meaning "I awake". Django — the D is silent as most everyone now knows — the nickname of the great Belgian-born jazz guitarist Django (originally Jean Baptiste) Reinhardt, makes a dynamic musical choice for any jazz aficionado.
I had exactly the same problem, and I found a solution in a GitHub issue:
import typing
if typing.TYPE_CHECKING:
from django.db.models.query import ValuesQuerySet
def _get_cars_for_validation(filter_: dict) -> 'ValuesQuerySet[Car, int]':
return (
Car.objects.filter(**filter_)
.values("id", "brand", "engine")
.order_by("id")
)
The if typing.TYPE_CHECKING
prevents the ImportError
when you run the program, because the nonexistent ValuesQuerySet
is only imported during the mypy check.
Also note that the annotation has to be a string: 'ValuesQuerySet[Car, int]'
.
The second argument to 'ValuesQuerySet[Car, int]'
is a mystery to me; the OP of the issue used int
"and it worked", in my case I tried a few other types, and all of them worked too; you may just as well use Any
, I suppose.
You can use reveal_type()
to inspect the type of the variable yourself.
You can also cast to QuerySet
:
from typing import cast
from django.db.models import QuerySet
return (
cast(QuerySet, Car.objects.filter(**filter_))
.values("id", "brand", "engine")
.order_by("id")
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With