Skip to content

Commit e512196

Browse files
committed
Allow single generic param for Field in ForeignKey
1 parent a16b9ba commit e512196

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

django-stubs/db/models/fields/related.pyi

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def resolve_relation(scope_model: type[Model], relation: str | type[Model]) -> s
2929
# __set__ value type
3030
_ST = TypeVar("_ST")
3131
# __get__ return type
32-
_GT = TypeVar("_GT")
32+
_GT = TypeVar("_GT", default=_ST)
3333

3434
class RelatedField(FieldCacheMixin, Field[_ST, _GT]):
3535
one_to_many: bool

tests/typecheck/models/test_related_fields.yml

+55
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,58 @@
142142
143143
class Other(models.Model):
144144
field = models.ForeignKey(MyModel, related_name="others", on_delete=models.CASCADE)
145+
146+
147+
- case: test_related_fields_with_two_generic_parameters
148+
main: |
149+
from myapp.models import Address, School, Student
150+
reveal_type(Student().school) # N: Revealed type is "myapp.models.School"
151+
reveal_type(Student().address) # N: Revealed type is "myapp.models.Address"
152+
s = Student()
153+
s.school = School()
154+
s.address = Address()
155+
installed_apps:
156+
- myapp
157+
files:
158+
- path: myapp/__init__.py
159+
- path: myapp/models.py
160+
content: |
161+
from django.db import models
162+
163+
class School(models.Model):
164+
pass
165+
166+
class Address(models.Model):
167+
pass
168+
169+
class Student(models.Model):
170+
school = models.ForeignKey["School","School"](to="School", on_delete=models.CASCADE)
171+
address = models.OneToOneField["Address","Address"](to="Address", on_delete=models.CASCADE)
172+
173+
174+
- case: test_related_fields_with_one_generic_parameter
175+
expect_fail: True
176+
main: |
177+
from myapp.models import Address, School, Student
178+
reveal_type(Student().school) # N: Revealed type is "myapp.models.School"
179+
reveal_type(Student().address) # N: Revealed type is "myapp.models.Address"
180+
s = Student()
181+
s.school = School()
182+
s.address = Address()
183+
installed_apps:
184+
- myapp
185+
files:
186+
- path: myapp/__init__.py
187+
- path: myapp/models.py
188+
content: |
189+
from django.db import models
190+
191+
class School(models.Model):
192+
pass
193+
194+
class Address(models.Model):
195+
pass
196+
197+
class Student(models.Model):
198+
school = models.ForeignKey["School"](to="School", on_delete=models.CASCADE)
199+
address = models.OneToOneField["Address"](to="Address", on_delete=models.CASCADE)

0 commit comments

Comments
 (0)