Package: django-stubs-pr730
pep484 stubs for DjangoThis package containstype stubsand a custom mypy plugin to provide more precise static types and type inference for Django framework. Django uses some Python "magic" that makes having precise types for some code patterns problematic. This is why we need this project. The final goal is to be able to get precise types for most common patterns.Installationpipinstalldjango-stubsTo make mypy aware of the plugin, you need to add[mypy]plugins=mypy_django_plugin.main[mypy.plugins.django-stubs]django_settings_module="myproject.settings"in yourmypy.iniorsetup.cfgfile.Two things happeining here:We need to explicitly list our plugin to be loaded bymypyOur plugin also requiresdjangosettings module (what you put intoDJANGO_SETTINGS_MODULEvariable) to be specifiedThis fully workingtyped boilerplatecan serve you as an example.Version compatibilityWe rely on differentdjangoandmypyversions:django-stubsmypy versiondjango versionpython version1.8.00.8122.2.x || 3.x^3.61.7.00.7902.2.x || 3.x^3.61.6.00.7802.2.x || 3.x^3.61.5.00.7702.2.x || 3.x^3.61.4.00.7602.2.x || 3.x^3.61.3.00.7502.2.x || 3.x^3.61.2.00.7302.2.x^3.61.1.00.7202.2.x^3.60.12.xold semantic analyzer (<0.711), dmypy support2.1.x^3.6FAQIs this an official Django project?No, it is not. We are independent from Django at the moment.
There's aproposalto merge our project into the Django itself.
You can show your support by liking the PR.Is it safe to use this in production?Yes, it is! This project does not affect your runtime at all.
It only affectsmypytype checking process.But, it does not make any sense to use this project withoutmypy.mypy crashes when I run it with this plugin installedCurrent implementation uses Django runtime to extract models information, so it will crash, if your installed apps ormodels.pyis not correct. For this same reason, you cannot usereveal_typeinside global scope of any Python file that will be executed fordjango.setup().In other words, if yourmanage.py runservercrashes, mypy will crash too.
You can also runmypywith--tboption to get extra information about the error.I cannot use QuerySet or Manager with type annotationsYou can get aTypeError: 'type' object is not subscriptablewhen you will try to useQuerySet[MyModel],Manager[MyModel]or some other Django-based Generic types.This happens because these Django classes do not support__class_getitem__magic method in runtime.You can go with ourdjango_stubs_exthelper, that patches all the types we use as Generic in django.Install it:pipinstalldjango-stubs-ext# as a production dependencyAnd then place in your top-level settings:importdjango_stubs_extdjango_stubs_ext.monkeypatch()You can use strings instead:'QuerySet[MyModel]'and'Manager[MyModel]', this way it will work as a type formypyand as a regularstrin runtime.How can I create a HttpRequest that's guaranteed to have an authenticated user?Django's built inHttpRequesthas the attributeuserthat resolves to the typeUnion[User,AnonymousUser]whereUseris the user model specified by theAUTH_USER_MODELsetting.If you want aHttpRequestthat you can type-annotate with where you know that the user is authenticated you can subclass the normalHttpRequestclass like so:fromdjango.httpimportHttpRequestfrommy_user_app.modelsimportMyUserclassAuthenticatedHttpRequest(HttpRequest):user:MyUserAnd then useAuthenticatedHttpRequestinstead of the standardHttpRequestfor when you know that the user is authenticated. For example in views using the@login_requireddecorator.My QuerySet methods are returning Any rather than my ModelQuerySet.as_manager()is not currently supported.If you are usingMyQuerySet.as_manager(), then yourManager/QuerySetmethods will all not be linked to your model.Example:fromdjango.dbimportmodelsclassMyModelQuerySet(models.QuerySet):passclassMyModel(models.Model):bar=models.IntegerField()objects=MyModelQuerySet.as_manager()defuse_my_model():foo=MyModel.objects.get(id=1)# This is `Any` but it should be `MyModel`returnfoo.xyz# No error, but there should beThere is a workaround: useManager.from_querysetinstead.Example:fromdjango.dbimportmodelsclassMyModelQuerySet(models.QuerySet):passMyModelManager=models.Manager.from_queryset(MyModelQuerySet)classMyModel(models.Model):bar=models.IntegerField()objects=MyModelManager()defuse_my_model():foo=MyModel.objects.get(id=1)returnfoo.xyz# Gives an errorRelated projectsawesome-python-typing- Awesome list of all typing-related things in Python.djangorestframework-stubs- Stubs for Django REST Framework.pytest-mypy-plugins-pytestplugin that we use for testingmypystubs and plugins.wemake-django-template- Create new typed Django projects in seconds.To get helpWe have Gitter here:https://gitter.im/mypy-django/LobbyIf you think you have more generic typing issue, please refer tohttps://github.com/python/mypyand their Gitter.ContributingThis project is open source and community driven. As such we encourage contributions big and small. You can contribute by doing any of the following:Contribute code (e.g. improve stubs, add plugin capabilities, write tests etc) - to do so please follow thecontribution guide.Assist in code reviews and discussions in issues.Identify bugs and issues and report theseYou can always also reach out in gitter to discuss your contributions!