-
-
Notifications
You must be signed in to change notification settings - Fork 484
Is it possible to create Protocols for Django Models #651
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
You don't have to inherit from a protocol. Just define them and use where you expect a matching structure. |
@sobolevn that sounds like a perfect solution, but I haven't been able to make it work. Do you have an example you could show me? |
@GlennS I hope, that this would be helpful to understand how But, while working with this docs, I have noticed that |
@sobolevn thank you very much! I'll read your new docs tomorrow and let you know how I get on. |
I think python/mypy#5481 is a much clearer description of the problem, so I'll close this one as a duplicate. Thanks again for your help @sobolevn , I think I understand this much better now. |
Changed my mind when I realised that other issue is on mypy itself. It's probably useful for people to be able to search django-stub's issues for "Protocol" and see this one. |
I just want to complement this issue with a (kind of) minimal example: from typing import Protocol
from django.db import models
class Person(Protcol):
@property
def given_name(self) -> str:
...
@property
def family_name(self) -> str:
...
class User(models.Model):
given_name = models.CharField(max_length=255)
family_name = models.CharField(max_length=255)
def x(person: Person) -> None:
return None
def y() -> None:
user = User.objects.get()
x(user)
return None Which gives me the following errors:
|
This is a mypy bug, because I don't think we can solve this quickly. |
I'm running into the same issue. Does someone have insight if it has become easier to fix since 2022? |
It's 2025 and I landed here lol. Should I give up trying to capture django models properties in a protocol? |
My aim is to create a
Protocol
which could match either a dataclass (ideally a frozen dataclass) or a Django model (I only really care about the getter).Does this seem like a plausible thing to expect to work? If so could you point me in the right direction?
The main issue is that the various types django-stubs defines to match Django fields like
IntegerField
andCharField
aren't compatible withint
,str
, and so on when you use those in a protocol.Obviously this does work when you use get and set from Django model fields in normal code, so I'm wondering where the magic lives which makes that happen (makes
CharField
compatible withstr
)?Sample error 1 (caused by
str
not being the same asCharField
):Sample error 2 (caused by Django model inheriting from a protocol which defines its field as a basic type):
Approaches I've tried (these are probably a little bit mad):
int
field. Django model won't accept it as a protocol.__get__
function overrides. If I fairly carefully copy parts of theField
definition https://github.com/typeddjango/django-stubs/blob/master/django-stubs/db/models/fields/__init__.pyi#L45 then I can make it partially work, but then I can't use my newly defined field protocol as if it were astr
elsewhere in the code.Union[CharField, str]
. I then have to tell the Django model which one it is, and I can't use it the field elsewhere in code.Here's some code for just approach (1):
The text was updated successfully, but these errors were encountered: