mirror of
https://github.com/davidhalter/django-stubs.git
synced 2025-12-06 12:14:28 +08:00
add support for typechecking of filter/get/exclude arguments (#183)
* add support for typechecking of filter/get/exclude arguments * linting
This commit is contained in:
215
test-data/typecheck/managers/querysets/test_filter.yml
Normal file
215
test-data/typecheck/managers/querysets/test_filter.yml
Normal file
@@ -0,0 +1,215 @@
|
||||
- case: filtering_with_proper_types
|
||||
main: |
|
||||
from myapp.models import User
|
||||
User.objects.filter(username='maksim')
|
||||
User.objects.get(username='maksim')
|
||||
User.objects.exclude(username='maksim')
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
username = models.CharField(max_length=100)
|
||||
|
||||
|
||||
- case: no_such_field_for_filter
|
||||
main: |
|
||||
from myapp.models import User
|
||||
User.objects.filter(unknown_field=True) # E: Cannot resolve keyword 'unknown_field' into field. Choices are: id
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
pass
|
||||
|
||||
|
||||
- case: filter_with_invalid_type
|
||||
main: |
|
||||
from myapp.models import User
|
||||
User.objects.filter(age='hello') # E: Incompatible type for lookup 'age': (got "str", expected "int")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
age = models.IntegerField()
|
||||
|
||||
|
||||
- case: filter_with_multiple_fields
|
||||
main: |
|
||||
from myapp.models import User
|
||||
User.objects.filter(age='hello', gender='world')
|
||||
installed_apps:
|
||||
- myapp
|
||||
out: |
|
||||
main:2: error: Incompatible type for lookup 'age': (got "str", expected "int")
|
||||
main:2: error: Incompatible type for lookup 'gender': (got "str", expected "int")
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
age = models.IntegerField()
|
||||
gender = models.IntegerField()
|
||||
|
||||
|
||||
- case: valid_filter_with_lookup
|
||||
main: |
|
||||
from myapp.models import User
|
||||
User.objects.filter(username__contains='hello')
|
||||
User.objects.filter(age__gt=1)
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
username = models.CharField(max_length=100)
|
||||
age = models.IntegerField()
|
||||
|
||||
|
||||
- case: invalid_filter_with_lookup
|
||||
main: |
|
||||
from myapp.models import User
|
||||
User.objects.filter(username__contains=1) # E: Incompatible type for lookup 'username__contains': (got "int", expected "str")
|
||||
User.objects.filter(username__icontains=1) # E: Incompatible type for lookup 'username__icontains': (got "int", expected "str")
|
||||
User.objects.filter(username__isnull=1) # E: Incompatible type for lookup 'username__isnull': (got "int", expected "bool")
|
||||
|
||||
User.objects.filter(created_at=User()) # E: Incompatible type for lookup 'created_at': (got "User", expected "Union[str, datetime]")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
username = models.CharField(max_length=100)
|
||||
age = models.IntegerField()
|
||||
created_at = models.DateTimeField()
|
||||
|
||||
- case: strings_are_allowed_for_exact_for_dates
|
||||
main: |
|
||||
from myapp.models import User
|
||||
User.objects.filter(created_at='2018')
|
||||
User.objects.filter(created_at__exact='2018')
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
created_at = models.DateTimeField()
|
||||
|
||||
|
||||
- case: related_model_foreign_key_lookups
|
||||
main: |
|
||||
from myapp.models import Blog, Publisher
|
||||
blog = Blog()
|
||||
publisher = Publisher()
|
||||
Blog.objects.filter(publisher=publisher)
|
||||
Blog.objects.filter(publisher_id=1)
|
||||
Blog.objects.filter(publisher__id=1)
|
||||
|
||||
Blog.objects.filter(publisher=blog) # E: Incompatible type for lookup 'publisher': (got "Blog", expected "Union[Publisher, int, None]")
|
||||
Blog.objects.filter(publisher_id='hello') # E: Incompatible type for lookup 'publisher_id': (got "str", expected "int")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Publisher(models.Model):
|
||||
pass
|
||||
class Blog(models.Model):
|
||||
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, related_name='blogs')
|
||||
|
||||
|
||||
- case: related_model_reverse_foreign_key_lookup
|
||||
main: |
|
||||
from myapp.models import Blog, Publisher
|
||||
blog = Blog()
|
||||
publisher = Publisher()
|
||||
Publisher.objects.filter(blogs=Blog())
|
||||
Publisher.objects.filter(blogs__id=1)
|
||||
|
||||
Publisher.objects.filter(blogs=publisher) # E: Incompatible type for lookup 'blogs': (got "Publisher", expected "Union[Blog, int, None]")
|
||||
Publisher.objects.filter(blogs__id=publisher) # E: Incompatible type for lookup 'blogs__id': (got "Publisher", expected "int")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Publisher(models.Model):
|
||||
pass
|
||||
class Blog(models.Model):
|
||||
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE, related_name='blogs')
|
||||
|
||||
|
||||
- case: many_to_many_lookups
|
||||
main: |
|
||||
from myapp.models import Book, Author
|
||||
book = Book()
|
||||
author = Author()
|
||||
|
||||
Book.objects.filter(authors=author)
|
||||
Book.objects.filter(authors=book) # E: Incompatible type for lookup 'authors': (got "Book", expected "Union[Author, int, None]")
|
||||
Book.objects.filter(authors='hello') # E: Incompatible type for lookup 'authors': (got "str", expected "Union[Author, int, None]")
|
||||
|
||||
Author.objects.filter(books=book)
|
||||
Author.objects.filter(books=author) # E: Incompatible type for lookup 'books': (got "Author", expected "Union[Book, int, None]")
|
||||
Author.objects.filter(books='hello') # E: Incompatible type for lookup 'books': (got "str", expected "Union[Book, int, None]")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class Book(models.Model):
|
||||
pass
|
||||
class Author(models.Model):
|
||||
books = models.ManyToManyField(Book, related_name='authors')
|
||||
|
||||
|
||||
- case: one_to_one_lookups
|
||||
main: |
|
||||
from myapp.models import User, Profile
|
||||
user = User()
|
||||
profile = Profile()
|
||||
User.objects.filter(profile=profile)
|
||||
User.objects.filter(profile=user) # E: Incompatible type for lookup 'profile': (got "User", expected "Union[Profile, int, None]")
|
||||
User.objects.filter(profile='hello') # E: Incompatible type for lookup 'profile': (got "str", expected "Union[Profile, int, None]")
|
||||
Profile.objects.filter(user=user)
|
||||
Profile.objects.filter(user=profile) # E: Incompatible type for lookup 'user': (got "Profile", expected "Union[User, int, None]")
|
||||
Profile.objects.filter(user='hello') # E: Incompatible type for lookup 'user': (got "str", expected "Union[User, int, None]")
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
- path: myapp/__init__.py
|
||||
- path: myapp/models.py
|
||||
content: |
|
||||
from django.db import models
|
||||
class User(models.Model):
|
||||
pass
|
||||
class Profile(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
|
||||
@@ -145,8 +145,7 @@
|
||||
main:3: note: Revealed type is 'Any'
|
||||
main:4: error: Cannot resolve keyword 'unknown' into field. Choices are: id, publisher, publisher_id
|
||||
main:4: note: Revealed type is 'Any'
|
||||
main:5: error: Lookups not supported yet
|
||||
main:5: note: Revealed type is 'Any'
|
||||
main:5: note: Revealed type is 'Tuple[Any]'
|
||||
installed_apps:
|
||||
- myapp
|
||||
files:
|
||||
|
||||
Reference in New Issue
Block a user