|
362 | 362 | num_posts = models.IntegerField() |
363 | 363 | text = models.CharField(max_length=100) |
364 | 364 |
|
| 365 | +- case: annotate_then_values_list_flat_slice_preserves_row_type |
| 366 | + main: | |
| 367 | + from typing import Iterable |
| 368 | + from typing_extensions import reveal_type |
| 369 | + from myapp.models import Blog |
| 370 | + from django.db.models import F |
| 371 | +
|
| 372 | + qs = Blog.objects.annotate(a=F("id")).values_list("id", flat=True) |
| 373 | + reveal_type(qs) # N: Revealed type is "django.db.models.query.QuerySet[myapp.models.Blog@AnnotatedWith[TypedDict({'a': Any})], int]" |
| 374 | + reveal_type(qs[:]) # N: Revealed type is "django.db.models.query.QuerySet[myapp.models.Blog@AnnotatedWith[TypedDict({'a': Any})], int]" |
| 375 | +
|
| 376 | + def get_blog_ids() -> Iterable[int]: |
| 377 | + return Blog.objects.annotate(a=F("id")).values_list("id", flat=True)[:] |
| 378 | +
|
| 379 | + # Also preserve non-flat tuple row types and TypedDict row types from values(). |
| 380 | + reveal_type(Blog.objects.annotate(a=F("id")).values_list("id", "text")[:]) # N: Revealed type is "django.db.models.query.QuerySet[myapp.models.Blog@AnnotatedWith[TypedDict({'a': Any})], tuple[int, str]]" |
| 381 | + reveal_type(Blog.objects.annotate(a=F("id")).values("id")[:]) # N: Revealed type is "django.db.models.query.QuerySet[myapp.models.Blog@AnnotatedWith[TypedDict({'a': Any})], TypedDict({'id': int})]" |
| 382 | + installed_apps: |
| 383 | + - myapp |
| 384 | + files: |
| 385 | + - path: myapp/__init__.py |
| 386 | + - path: myapp/models.py |
| 387 | + content: | |
| 388 | + from django.db import models |
| 389 | + class Blog(models.Model): |
| 390 | + text = models.CharField(max_length=100) |
| 391 | +
|
365 | 392 | - case: test_annotate_with_filter |
366 | 393 | main: | |
367 | 394 | from django.db import models |
|
0 commit comments