django-stubs
django-stubs copied to clipboard
values_list returns Optional[Type] for field when field has a default value and is not nullable
Bug report
What's wrong
from django.db import models
class MyModel(models.Model):
my_field = models.DecimalField(decimal_places=2, max_digits=10, default=0)
result = MyModel.objects.values_list('my_field', flat=True).get(id=1)
reveal_type(result) # Revealed type is: Optional[Decimal]
How is that should be
The type of result
is expected to be Decimal
as the field is not nullable.
It seems to be due to the use of the default
value for the field.
The culprit is probably this line: https://github.com/typeddjango/django-stubs/blob/31e795016f154309e675c85616f4f8af033c0860/mypy_django_plugin/django/context.py#L241
It should return False
if there is a default instead.
There doesn't seem to be a test-case for this in: https://github.com/typeddjango/django-stubs/blob/31e795016f154309e675c85616f4f8af033c0860/test-data/typecheck/managers/querysets/test_values_list.yml
===
Edit:
It seems that the function should still return True if there is a default if method
is create
or __init__
, but not in other cases.
It works when I change the line to:
if isinstance(field, Field) and field.has_default() and field.default is None
.
Rationelle: If it has a default, and the default is not None than it's not an optional.
@rvanlaar looks like a valid solution. The only thing that I would formulate this rule as "field type is Union[FieldType, DefaulValueType]
". PRs are welcome!
If this does not involve anything else, #717 fixes this for me. Nevertheless I didn't really understand @sobolevn's last comment on the field type, so this might still need some changes.
I would really appreciate it if you can merge it :)
Is something missing here? Looks like the pull request is approved, but not merged yet.
Closed via #1020