Closed argilya closed 2 years ago
Oof this is a tricky problem with the stubs. Basically there isn’t a way to add fields to an existing type with Python’s typing. One option is to create a protocol that mirrors the shape of the User, but then you’ll need to update all the functions that take a User as a param accordingly.
I think your approach of copying all the fields to your own type stub should also work, it’s also pretty manual as you’ve noticed.
Thank you for the response. I'll go with the last option, since I won't have to refactor the code base.
Hello,
The django code base I work with makes use of django's default
User
model. I would like to annotate this model with relation managers. For example, if there is a table calledPosts
that has a FK fromUser
, I would like Pyright to recognize thatreveal_type(User().posts)
isManger[Post]
. I have read your README on how to achieve this with your own models. However,User
is defined by django, and so I can't edit it.How do I annotate djagno's
User
to letPyright
know thatUser().posts
is legal? This question is probably a bit naive, but I am new to both django and to python types, and so I would appreciate the help!I came up with 2 ways to solve this problem:
Define a superset of
User
with the manger annotation included, like so:This approach works, but I am unhappy with it, because I will have to refactor the entire code base to use
AnnotatedUser
instead ofUser
. I would like to avoid that.So I figured I could just make a custom type stub for
User
that includedposts: Manager[Post]
. That's where I ran into problems. I wrote a stub like so:from typing import TYPE_CHECKING
if TYPE_CHECKING:
from posts.models import Post
from django.db.models import Manager from django.contrib.auth.models import AbstractUser
I just copied the User stub from django-stubs and added
posts
class User(AbstractUser): objects: Manager[User]
posts: Manager[Post]