Fix nullability of blank charfields in values and values_list (#1020)

Char fields with blank=True set should not be considered nullable in the
context of values() and values_list() querysets.

I'm also not a huge fan of the way these fields are made optional in the
constructur to the model classes, it feels like it would be better to
mark the arguments as having a default value, rather than allow sending
in None, but I'd rather keep this fix small and look at the overall
problem at a later point.
This commit is contained in:
Sigurd Ljødal
2022-06-25 13:37:25 +02:00
committed by GitHub
parent dd0fe02367
commit 1a29ad4f97
3 changed files with 37 additions and 0 deletions

View File

@@ -263,6 +263,9 @@ class DjangoContext:
return attname
def get_field_nullability(self, field: Union[Field, ForeignObjectRel], method: Optional[str]) -> bool:
if method in ("values", "values_list"):
return field.null
nullable = field.null
if not nullable and isinstance(field, CharField) and field.blank:
return True

View File

@@ -124,3 +124,21 @@
pass
class Book(models.Model):
authors = models.ManyToManyField(Author, related_name='books')
- case: queryset_values_blank_charfield
main: |
from myapp.models import Blog
values = Blog.objects.values('text').get()
reveal_type(values) # N: Revealed type is "TypedDict({'text': builtins.str})"
reveal_type(values["text"]) # N: Revealed type is "builtins.str"
installed_apps:
- myapp
files:
- path: myapp/__init__.py
- path: myapp/models.py
content: |
from django.db import models
class Blog(models.Model):
num_posts = models.IntegerField()
text = models.CharField(max_length=100, blank=True)

View File

@@ -265,3 +265,19 @@
pass
class Book(models.Model):
authors = models.ManyToManyField(Author, related_name='books')
- case: queryset_values_list_blank_charfield
main: |
from myapp.models import Blog
values = Blog.objects.values_list('text').get()
reveal_type(values) # N: Revealed type is "Tuple[builtins.str]"
installed_apps:
- myapp
files:
- path: myapp/__init__.py
- path: myapp/models.py
content: |
from django.db import models
class Blog(models.Model):
num_posts = models.IntegerField()
text = models.CharField(max_length=100, blank=True)