added new tests and refactored some previous tests
* removed tests that essentially covered form/field rendering * added more edge-case tests (Proxy models, MTI models, filtering through relationships) * moved most of the tests which performed queryset filtering to new filtering_tests.py * added "pragma: nocover" in a few places for coverage.py to omit for reporting * included fix for generic view error inside of ImproperlyConfigured handler
This commit is contained in:
parent
ea2e1fc61c
commit
ec169c901c
|
@ -13,7 +13,8 @@ from django.utils.text import capfirst
|
|||
|
||||
try:
|
||||
from django.db.models.constants import LOOKUP_SEP
|
||||
except ImportError: # Django < 1.5 fallback
|
||||
except ImportError: # pragma: nocover
|
||||
# Django < 1.5 fallback
|
||||
from django.db.models.sql.constants import LOOKUP_SEP # noqa
|
||||
|
||||
from .filters import (Filter, CharFilter, BooleanFilter,
|
||||
|
|
|
@ -48,7 +48,8 @@ class FilterMixin(object):
|
|||
msg = ("'%s' does not define a 'model' and the view '%s' does "
|
||||
"not return a valid queryset from 'get_queryset'. You "
|
||||
"must fix one of them.")
|
||||
raise ImproperlyConfigured(msg % self.__class__.__name__)
|
||||
args = (filterset_class.__name__, self.__class__.__name__)
|
||||
raise ImproperlyConfigured(msg % args)
|
||||
return kwargs
|
||||
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ from django.db.models.fields import BLANK_CHOICE_DASH
|
|||
from django.forms.widgets import flatatt
|
||||
try:
|
||||
from django.utils.encoding import force_text
|
||||
except:
|
||||
except: # pragma: nocover
|
||||
from django.utils.encoding import force_unicode as force_text # noqa
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import ugettext as _
|
||||
|
|
|
@ -23,6 +23,7 @@ from django_filters.filters import NumberFilter
|
|||
from django_filters.filters import RangeFilter
|
||||
from django_filters.filters import DateRangeFilter
|
||||
from django_filters.filters import AllValuesFilter
|
||||
from django_filters.filters import LOOKUP_TYPES
|
||||
|
||||
|
||||
class FilterTests(TestCase):
|
||||
|
@ -41,15 +42,24 @@ class FilterTests(TestCase):
|
|||
field = f.field
|
||||
self.assertIsInstance(field, forms.Field)
|
||||
|
||||
def test_field_with_single_lookup_type(self):
|
||||
f = Filter(lookup_type='iexact')
|
||||
field = f.field
|
||||
self.assertIsInstance(field, forms.Field)
|
||||
|
||||
def test_field_with_none_lookup_type(self):
|
||||
f = Filter(lookup_type=None)
|
||||
field = f.field
|
||||
self.assertIsInstance(field, LookupTypeField)
|
||||
choice_field = field.fields[1]
|
||||
self.assertEqual(len(choice_field.choices), len(LOOKUP_TYPES))
|
||||
|
||||
def test_field_with_list_lookup_type(self):
|
||||
f = Filter(lookup_type=('istartswith', 'iendswith'))
|
||||
field = f.field
|
||||
self.assertIsInstance(field, LookupTypeField)
|
||||
choice_field = field.fields[1]
|
||||
self.assertEqual(len(choice_field.choices), 2)
|
||||
|
||||
def test_field_params(self):
|
||||
with mock.patch.object(Filter, 'field_class',
|
||||
|
@ -267,6 +277,7 @@ class ModelChoiceFilterTests(TestCase):
|
|||
f = ModelChoiceFilter(queryset=qs)
|
||||
field = f.field
|
||||
self.assertIsInstance(field, forms.ModelChoiceField)
|
||||
self.assertEqual(field.queryset, qs)
|
||||
|
||||
|
||||
class ModelMultipleChoiceFilterTests(TestCase):
|
||||
|
@ -281,6 +292,7 @@ class ModelMultipleChoiceFilterTests(TestCase):
|
|||
f = ModelMultipleChoiceFilter(queryset=qs)
|
||||
field = f.field
|
||||
self.assertIsInstance(field, forms.ModelMultipleChoiceField)
|
||||
self.assertEqual(field.queryset, qs)
|
||||
|
||||
|
||||
class NumberFilterTests(TestCase):
|
||||
|
|
|
@ -0,0 +1,972 @@
|
|||
from __future__ import absolute_import
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import mock
|
||||
import datetime
|
||||
|
||||
from django.utils import unittest
|
||||
from django.test import TestCase
|
||||
from django.utils import six
|
||||
from django.utils.timezone import now
|
||||
from django.utils import timezone
|
||||
|
||||
from django_filters.filterset import FilterSet
|
||||
from django_filters.filters import AllValuesFilter
|
||||
from django_filters.filters import CharFilter
|
||||
from django_filters.filters import ChoiceFilter
|
||||
from django_filters.filters import DateRangeFilter
|
||||
# from django_filters.filters import DateTimeFilter
|
||||
from django_filters.filters import MultipleChoiceFilter
|
||||
from django_filters.filters import NumberFilter
|
||||
from django_filters.filters import RangeFilter
|
||||
# from django_filters.widgets import LinkWidget
|
||||
|
||||
from .models import User
|
||||
from .models import Comment
|
||||
from .models import Book
|
||||
# from .models import Restaurant
|
||||
from .models import Article
|
||||
# from .models import NetworkSetting
|
||||
# from .models import SubnetMaskField
|
||||
from .models import Company
|
||||
from .models import Location
|
||||
from .models import Account
|
||||
from .models import Profile
|
||||
from .models import STATUS_CHOICES
|
||||
|
||||
|
||||
class CharFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
b1 = Book.objects.create(
|
||||
title="Ender's Game", price='1.00', average_rating=3.0)
|
||||
b2 = Book.objects.create(
|
||||
title="Rainbow Six", price='1.00', average_rating=3.0)
|
||||
b3 = Book.objects.create(
|
||||
title="Snowcrash", price='1.00', average_rating=3.0)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['title']
|
||||
|
||||
qs = Book.objects.all()
|
||||
f = F(queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [b1.pk, b2.pk, b3.pk],
|
||||
lambda o: o.pk, ordered=False)
|
||||
f = F({'title': 'Snowcrash'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [b3.pk], lambda o: o.pk)
|
||||
|
||||
|
||||
class BooleanFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
User.objects.create(username='alex', is_active=False)
|
||||
User.objects.create(username='jacob', is_active=True)
|
||||
User.objects.create(username='aaron', is_active=False)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['is_active']
|
||||
|
||||
qs = User.objects.all()
|
||||
|
||||
# '2' and '3' are how the field expects the data from the browser
|
||||
f = F({'is_active': '2'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['jacob'], lambda o: o.username, False)
|
||||
|
||||
f = F({'is_active': '3'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs,
|
||||
['alex', 'aaron'],
|
||||
lambda o: o.username, False)
|
||||
|
||||
f = F({'is_active': '1'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs,
|
||||
['alex', 'aaron', 'jacob'],
|
||||
lambda o: o.username, False)
|
||||
|
||||
|
||||
class ChoiceFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
User.objects.create(username='alex', status=1)
|
||||
User.objects.create(username='jacob', status=2)
|
||||
User.objects.create(username='aaron', status=2)
|
||||
User.objects.create(username='carl', status=0)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status']
|
||||
|
||||
f = F()
|
||||
self.assertQuerysetEqual(f.qs,
|
||||
['aaron', 'alex', 'jacob', 'carl'],
|
||||
lambda o: o.username, False)
|
||||
f = F({'status': '1'})
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username, False)
|
||||
|
||||
f = F({'status': '2'})
|
||||
self.assertQuerysetEqual(f.qs, ['jacob', 'aaron'],
|
||||
lambda o: o.username, False)
|
||||
|
||||
f = F({'status': '0'})
|
||||
self.assertQuerysetEqual(f.qs, ['carl'], lambda o: o.username, False)
|
||||
|
||||
|
||||
class MultipleChoiceFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
User.objects.create(username='alex', status=1)
|
||||
User.objects.create(username='jacob', status=2)
|
||||
User.objects.create(username='aaron', status=2)
|
||||
User.objects.create(username='carl', status=0)
|
||||
|
||||
class F(FilterSet):
|
||||
status = MultipleChoiceFilter(choices=STATUS_CHOICES)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status']
|
||||
|
||||
qs = User.objects.all().order_by('username')
|
||||
f = F(queryset=qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ['aaron', 'jacob', 'alex', 'carl'],
|
||||
lambda o: o.username, False)
|
||||
|
||||
f = F({'status': ['0']}, queryset=qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ['carl'], lambda o: o.username)
|
||||
|
||||
f = F({'status': ['0', '1']}, queryset=qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ['alex', 'carl'], lambda o: o.username)
|
||||
|
||||
f = F({'status': ['0', '1', '2']}, queryset=qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ['aaron', 'alex', 'carl', 'jacob'], lambda o: o.username)
|
||||
|
||||
|
||||
class DateFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
today = now().date()
|
||||
timestamp = now().time().replace(microsecond=0)
|
||||
last_week = today - datetime.timedelta(days=7)
|
||||
check_date = six.text_type(last_week)
|
||||
u = User.objects.create(username='alex')
|
||||
Comment.objects.create(author=u, time=timestamp, date=today)
|
||||
Comment.objects.create(author=u, time=timestamp, date=last_week)
|
||||
Comment.objects.create(author=u, time=timestamp, date=today)
|
||||
Comment.objects.create(author=u, time=timestamp, date=last_week)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['date']
|
||||
|
||||
f = F({'date': check_date}, queryset=Comment.objects.all())
|
||||
self.assertEqual(len(f.qs), 2)
|
||||
self.assertQuerysetEqual(f.qs, [2, 4], lambda o: o.pk)
|
||||
|
||||
|
||||
class TimeFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
today = now().date()
|
||||
now_time = now().time().replace(microsecond=0)
|
||||
ten_min_ago = (now() - datetime.timedelta(minutes=10))
|
||||
fixed_time = ten_min_ago.time().replace(microsecond=0)
|
||||
check_time = six.text_type(fixed_time)
|
||||
u = User.objects.create(username='alex')
|
||||
Comment.objects.create(author=u, time=now_time, date=today)
|
||||
Comment.objects.create(author=u, time=fixed_time, date=today)
|
||||
Comment.objects.create(author=u, time=now_time, date=today)
|
||||
Comment.objects.create(author=u, time=fixed_time, date=today)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['time']
|
||||
|
||||
f = F({'time': check_time}, queryset=Comment.objects.all())
|
||||
self.assertEqual(len(f.qs), 2)
|
||||
self.assertQuerysetEqual(f.qs, [2, 4], lambda o: o.pk)
|
||||
|
||||
|
||||
class DateTimeFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
now_dt = now()
|
||||
ten_min_ago = now_dt - datetime.timedelta(minutes=10)
|
||||
one_day_ago = now_dt - datetime.timedelta(days=1)
|
||||
u = User.objects.create(username='alex')
|
||||
Article.objects.create(author=u, published=now_dt)
|
||||
Article.objects.create(author=u, published=ten_min_ago)
|
||||
Article.objects.create(author=u, published=one_day_ago)
|
||||
|
||||
tz = timezone.get_current_timezone()
|
||||
# make naive, like a browser would send
|
||||
local_ten_min_ago = timezone.make_naive(ten_min_ago, tz)
|
||||
check_dt = six.text_type(local_ten_min_ago)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = ['published']
|
||||
|
||||
qs = Article.objects.all()
|
||||
f = F({'published': ten_min_ago}, queryset=qs)
|
||||
self.assertEqual(len(f.qs), 1)
|
||||
self.assertQuerysetEqual(f.qs, [2], lambda o: o.pk)
|
||||
|
||||
# this is how it would come through a browser
|
||||
f = F({'published': check_dt}, queryset=qs)
|
||||
self.assertEqual(len(f.qs), 1,
|
||||
"%s isn't matching %s when cleaned" % (check_dt, ten_min_ago))
|
||||
self.assertQuerysetEqual(f.qs, [2], lambda o: o.pk)
|
||||
|
||||
|
||||
class ModelChoiceFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
jacob = User.objects.create(username='jacob')
|
||||
date = now().date()
|
||||
time = now().time()
|
||||
Comment.objects.create(author=jacob, time=time, date=date)
|
||||
Comment.objects.create(author=alex, time=time, date=date)
|
||||
Comment.objects.create(author=jacob, time=time, date=date)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['author']
|
||||
|
||||
qs = Comment.objects.all()
|
||||
f = F({'author': jacob.pk}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [1, 3], lambda o: o.pk)
|
||||
|
||||
|
||||
class ModelMultipleChoiceFilterTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
User.objects.create(username='jacob')
|
||||
aaron = User.objects.create(username='aaron')
|
||||
b1 = Book.objects.create(title="Ender's Game", price='1.00',
|
||||
average_rating=3.0)
|
||||
b2 = Book.objects.create(title="Rainbow Six", price='1.00',
|
||||
average_rating=3.0)
|
||||
b3 = Book.objects.create(title="Snowcrash", price='1.00',
|
||||
average_rating=3.0)
|
||||
Book.objects.create(title="Stranger in a Strage Land", price='1.00',
|
||||
average_rating=3.0)
|
||||
alex.favorite_books = [b1, b2]
|
||||
aaron.favorite_books = [b1, b3]
|
||||
|
||||
def test_filtering(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books']
|
||||
|
||||
qs = User.objects.all().order_by('username')
|
||||
f = F({'favorite_books': ['1']}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['aaron', 'alex'], lambda o: o.username)
|
||||
|
||||
f = F({'favorite_books': ['1', '3']}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['aaron', 'alex'], lambda o: o.username)
|
||||
|
||||
f = F({'favorite_books': ['2']}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
f = F({'favorite_books': ['4']}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [], lambda o: o.username)
|
||||
|
||||
|
||||
class NumberFilterTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
Book.objects.create(title="Ender's Game", price='10.0',
|
||||
average_rating=4.7999999999999998)
|
||||
Book.objects.create(title="Rainbow Six", price='15.0',
|
||||
average_rating=4.5999999999999996)
|
||||
Book.objects.create(title="Snowcrash", price='20.0',
|
||||
average_rating=4.2999999999999998)
|
||||
|
||||
def test_filtering(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['price']
|
||||
|
||||
f = F({'price': 10}, queryset=Book.objects.all())
|
||||
self.assertQuerysetEqual(f.qs, ['Ender\'s Game'], lambda o: o.title)
|
||||
|
||||
def test_filtering_with_single_lookup_type(self):
|
||||
class F(FilterSet):
|
||||
price = NumberFilter(lookup_type='lt')
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['price']
|
||||
|
||||
f = F({'price': 16}, queryset=Book.objects.all().order_by('title'))
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ['Ender\'s Game', 'Rainbow Six'], lambda o: o.title)
|
||||
|
||||
def test_filtering_with_multiple_lookup_types(self):
|
||||
class F(FilterSet):
|
||||
price = NumberFilter(lookup_type=['lt', 'gt'])
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['price']
|
||||
|
||||
qs = Book.objects.all()
|
||||
f = F({'price_0': '15', 'price_1': 'lt'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['Ender\'s Game'], lambda o: o.title)
|
||||
f = F({'price_0': '15', 'price_1': 'lt'})
|
||||
self.assertQuerysetEqual(f.qs, ['Ender\'s Game'], lambda o: o.title)
|
||||
f = F({'price_0': '', 'price_1': 'lt'})
|
||||
self.assertQuerysetEqual(f.qs,
|
||||
['Ender\'s Game', 'Rainbow Six', 'Snowcrash'],
|
||||
lambda o: o.title, ordered=False)
|
||||
|
||||
class F(FilterSet):
|
||||
price = NumberFilter(lookup_type=['lt', 'gt', 'exact'])
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['price']
|
||||
|
||||
f = F({'price_0': '15'})
|
||||
self.assertQuerysetEqual(f.qs, ['Rainbow Six'], lambda o: o.title)
|
||||
|
||||
|
||||
class RangeFilterTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
Book.objects.create(title="Ender's Game", price='10.0',
|
||||
average_rating=4.7999999999999998)
|
||||
Book.objects.create(title="Rainbow Six", price='15.0',
|
||||
average_rating=4.5999999999999996)
|
||||
Book.objects.create(title="Snowcrash", price='20.0',
|
||||
average_rating=4.2999999999999998)
|
||||
|
||||
def test_filtering(self):
|
||||
class F(FilterSet):
|
||||
price = RangeFilter()
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['price']
|
||||
|
||||
qs = Book.objects.all().order_by('title')
|
||||
f = F(queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs,
|
||||
['Ender\'s Game', 'Rainbow Six', 'Snowcrash'],
|
||||
lambda o: o.title)
|
||||
f = F({'price_0': '5', 'price_1': '15'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs,
|
||||
['Ender\'s Game', 'Rainbow Six'],
|
||||
lambda o: o.title)
|
||||
|
||||
|
||||
@unittest.skip('date-range is funky')
|
||||
class DateRangeFilterTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
today = now().date()
|
||||
five_days_ago = today - datetime.timedelta(days=5)
|
||||
two_weeks_ago = today - datetime.timedelta(days=14)
|
||||
two_months_ago = today - datetime.timedelta(days=62)
|
||||
two_years_ago = today - datetime.timedelta(days=800)
|
||||
alex = User.objects.create(username='alex')
|
||||
time = now().time()
|
||||
Comment.objects.create(date=two_weeks_ago, author=alex, time=time)
|
||||
Comment.objects.create(date=two_years_ago, author=alex, time=time)
|
||||
Comment.objects.create(date=five_days_ago, author=alex, time=time)
|
||||
Comment.objects.create(date=today, author=alex, time=time)
|
||||
Comment.objects.create(date=two_months_ago, author=alex, time=time)
|
||||
|
||||
def test_filtering_for_year(self):
|
||||
class F(FilterSet):
|
||||
date = DateRangeFilter()
|
||||
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['date']
|
||||
|
||||
f = F({'date': '4'}) # this year
|
||||
self.assertQuerysetEqual(f.qs, [1, 3, 4, 5], lambda o: o.pk, False)
|
||||
|
||||
def test_filtering_for_month(self):
|
||||
class F(FilterSet):
|
||||
date = DateRangeFilter()
|
||||
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['date']
|
||||
|
||||
f = F({'date': '3'}) # this month
|
||||
self.assertQuerysetEqual(f.qs, [1, 3, 4], lambda o: o.pk, False)
|
||||
|
||||
@unittest.expectedFailure
|
||||
def test_filtering_for_week(self):
|
||||
class F(FilterSet):
|
||||
date = DateRangeFilter()
|
||||
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['date']
|
||||
|
||||
f = F({'date': '2'}) # this week
|
||||
self.assertQuerysetEqual(f.qs, [3, 4], lambda o: o.pk, False)
|
||||
|
||||
def test_filtering_for_today(self):
|
||||
class F(FilterSet):
|
||||
date = DateRangeFilter()
|
||||
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['date']
|
||||
|
||||
f = F({'date': '1'}) # today
|
||||
self.assertQuerysetEqual(f.qs, [4], lambda o: o.pk, False)
|
||||
|
||||
# it will be difficult to test for TZ related issues, where "today" means
|
||||
# different things to both user and server.
|
||||
|
||||
|
||||
class AllValuesFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
User.objects.create(username='alex')
|
||||
User.objects.create(username='jacob')
|
||||
User.objects.create(username='aaron')
|
||||
|
||||
class F(FilterSet):
|
||||
username = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['username']
|
||||
|
||||
self.assertEqual(list(F().qs), list(User.objects.all()))
|
||||
self.assertEqual(list(F({'username': 'alex'})),
|
||||
[User.objects.get(username='alex')])
|
||||
self.assertEqual(list(F({'username': 'jose'})),
|
||||
list(User.objects.all()))
|
||||
|
||||
|
||||
class O2ORelationshipTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
a1 = Account.objects.create(
|
||||
name='account1', in_good_standing=False, friendly=False)
|
||||
a2 = Account.objects.create(
|
||||
name='account2', in_good_standing=True, friendly=True)
|
||||
a3 = Account.objects.create(
|
||||
name='account3', in_good_standing=True, friendly=False)
|
||||
a4 = Account.objects.create(
|
||||
name='account4', in_good_standing=False, friendly=True)
|
||||
Profile.objects.create(account=a1, likes_coffee=True, likes_tea=False)
|
||||
Profile.objects.create(account=a2, likes_coffee=False, likes_tea=True)
|
||||
Profile.objects.create(account=a3, likes_coffee=True, likes_tea=True)
|
||||
Profile.objects.create(account=a4, likes_coffee=False, likes_tea=False)
|
||||
|
||||
def test_o2o_relation(self):
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Profile
|
||||
fields = ('account',)
|
||||
|
||||
f = F()
|
||||
self.assertEqual(f.qs.count(), 4)
|
||||
|
||||
f = F({'account': 1})
|
||||
self.assertEqual(f.qs.count(), 1)
|
||||
self.assertQuerysetEqual(f.qs, [1], lambda o: o.pk)
|
||||
|
||||
def test_reverse_o2o_relation(self):
|
||||
with self.assertRaises(AttributeError):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Account
|
||||
fields = ('profile',)
|
||||
|
||||
def test_o2o_relation_attribute(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Profile
|
||||
fields = ('account__in_good_standing',)
|
||||
|
||||
f = F()
|
||||
self.assertEqual(f.qs.count(), 4)
|
||||
|
||||
f = F({'account__in_good_standing': '2'})
|
||||
self.assertEqual(f.qs.count(), 2)
|
||||
self.assertQuerysetEqual(f.qs, [2, 3], lambda o: o.pk)
|
||||
|
||||
def test_o2o_relation_attribute2(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Profile
|
||||
fields = ('account__in_good_standing', 'account__friendly',)
|
||||
|
||||
f = F()
|
||||
self.assertEqual(f.qs.count(), 4)
|
||||
|
||||
f = F({'account__in_good_standing': '2', 'account__friendly': '2'})
|
||||
self.assertEqual(f.qs.count(), 1)
|
||||
self.assertQuerysetEqual(f.qs, [2], lambda o: o.pk)
|
||||
|
||||
def test_reverse_o2o_relation_attribute(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Account
|
||||
fields = ('profile__likes_coffee',)
|
||||
|
||||
f = F()
|
||||
self.assertEqual(f.qs.count(), 4)
|
||||
|
||||
f = F({'profile__likes_coffee': '2'})
|
||||
self.assertEqual(f.qs.count(), 2)
|
||||
self.assertQuerysetEqual(f.qs, [1, 3], lambda o: o.pk)
|
||||
|
||||
def test_reverse_o2o_relation_attribute2(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Account
|
||||
fields = ('profile__likes_coffee', 'profile__likes_tea')
|
||||
|
||||
f = F()
|
||||
self.assertEqual(f.qs.count(), 4)
|
||||
|
||||
f = F({'profile__likes_coffee': '2', 'profile__likes_tea': '2'})
|
||||
self.assertEqual(f.qs.count(), 1)
|
||||
self.assertQuerysetEqual(f.qs, [3], lambda o: o.pk)
|
||||
|
||||
|
||||
class FKRelationshipTests(TestCase):
|
||||
|
||||
def test_fk_relation(self):
|
||||
company1 = Company.objects.create(name='company1')
|
||||
company2 = Company.objects.create(name='company2')
|
||||
Location.objects.create(
|
||||
company=company1, open_days="some", zip_code="90210")
|
||||
Location.objects.create(
|
||||
company=company2, open_days="WEEKEND", zip_code="11111")
|
||||
Location.objects.create(
|
||||
company=company1, open_days="monday", zip_code="12345")
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Location
|
||||
fields = ('company',)
|
||||
|
||||
f = F()
|
||||
self.assertEqual(f.qs.count(), 3)
|
||||
|
||||
f = F({'company': 1})
|
||||
self.assertEqual(f.qs.count(), 2)
|
||||
self.assertQuerysetEqual(f.qs, [1, 3], lambda o: o.pk)
|
||||
|
||||
def test_reverse_fk_relation(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
jacob = User.objects.create(username='jacob')
|
||||
date = now().date()
|
||||
time = now().time()
|
||||
Comment.objects.create(text='comment 1',
|
||||
author=jacob, time=time, date=date)
|
||||
Comment.objects.create(text='comment 2',
|
||||
author=alex, time=time, date=date)
|
||||
Comment.objects.create(text='comment 3',
|
||||
author=jacob, time=time, date=date)
|
||||
|
||||
with self.assertRaises(AttributeError):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['comments']
|
||||
|
||||
# qs = User.objects.all()
|
||||
# f = F({'comment': 2}, queryset=qs)
|
||||
# self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
with self.assertRaises(AttributeError):
|
||||
class F(FilterSet):
|
||||
comment = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['comments']
|
||||
|
||||
# f = F({'comments': 2}, queryset=qs)
|
||||
# self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
def test_fk_relation_attribute(self):
|
||||
now_dt = now()
|
||||
alex = User.objects.create(username='alex')
|
||||
jacob = User.objects.create(username='jacob')
|
||||
User.objects.create(username='aaron')
|
||||
|
||||
Article.objects.create(author=alex, published=now_dt)
|
||||
Article.objects.create(author=jacob, published=now_dt)
|
||||
Article.objects.create(author=alex, published=now_dt)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = ['author__username']
|
||||
|
||||
self.assertEqual(list(F.base_filters), ['author__username'])
|
||||
self.assertEqual(F({'author__username': 'alex'}).qs.count(), 2)
|
||||
self.assertEqual(F({'author__username': 'jacob'}).qs.count(), 1)
|
||||
|
||||
class F(FilterSet):
|
||||
author__username = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = ['author__username']
|
||||
|
||||
self.assertEqual(F({'author__username': 'alex'}).qs.count(), 2)
|
||||
|
||||
def test_reverse_fk_relation_attribute(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
jacob = User.objects.create(username='jacob')
|
||||
date = now().date()
|
||||
time = now().time()
|
||||
Comment.objects.create(text='comment 1',
|
||||
author=jacob, time=time, date=date)
|
||||
Comment.objects.create(text='comment 2',
|
||||
author=alex, time=time, date=date)
|
||||
Comment.objects.create(text='comment 3',
|
||||
author=jacob, time=time, date=date)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['comments__text']
|
||||
|
||||
qs = User.objects.all()
|
||||
f = F({'comments__text': 'comment 2'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
class F(FilterSet):
|
||||
comments__text = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['comments__text']
|
||||
|
||||
f = F({'comments__text': 'comment 2'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
@unittest.skip('todo - need correct models')
|
||||
def test_fk_relation_multiple_attributes(self):
|
||||
pass
|
||||
|
||||
@unittest.expectedFailure
|
||||
def test_reverse_fk_relation_multiple_attributes(self):
|
||||
company = Company.objects.create(name='company')
|
||||
Location.objects.create(
|
||||
company=company, open_days="some", zip_code="90210")
|
||||
Location.objects.create(
|
||||
company=company, open_days="WEEKEND", zip_code="11111")
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Company
|
||||
fields = ('locations__zip_code', 'locations__open_days')
|
||||
|
||||
f = F({'locations__zip_code': '90210',
|
||||
'locations__open_days': 'WEEKEND'})
|
||||
self.assertEqual(f.qs.count(), 0)
|
||||
|
||||
|
||||
class M2MRelationshipTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
alex = User.objects.create(username='alex', status=1)
|
||||
User.objects.create(username='jacob', status=1)
|
||||
aaron = User.objects.create(username='aaron', status=1)
|
||||
b1 = Book.objects.create(title="Ender's Game", price='1.00',
|
||||
average_rating=3.0)
|
||||
b2 = Book.objects.create(title="Rainbow Six", price='2.00',
|
||||
average_rating=4.0)
|
||||
b3 = Book.objects.create(title="Snowcrash", price='1.00',
|
||||
average_rating=4.0)
|
||||
Book.objects.create(title="Stranger in a Strage Land", price='2.00',
|
||||
average_rating=3.0)
|
||||
alex.favorite_books = [b1, b2]
|
||||
aaron.favorite_books = [b1, b3]
|
||||
|
||||
def test_m2m_relation(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books']
|
||||
|
||||
qs = User.objects.all().order_by('username')
|
||||
f = F({'favorite_books': ['1']}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['aaron', 'alex'], lambda o: o.username)
|
||||
|
||||
f = F({'favorite_books': ['1', '3']}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['aaron', 'alex'], lambda o: o.username)
|
||||
|
||||
f = F({'favorite_books': ['2']}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
f = F({'favorite_books': ['4']}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [], lambda o: o.username)
|
||||
|
||||
def test_reverse_m2m_relation(self):
|
||||
with self.assertRaises(AttributeError):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['lovers']
|
||||
|
||||
# qs = User.objects.all()
|
||||
# f = F({'lovers': [1]}, queryset=qs)
|
||||
# self.assertQuerysetEqual(
|
||||
# f.qs, ["Ender's Game", "Rainbow Six"], lambda o: o.title)
|
||||
|
||||
with self.assertRaises(AttributeError):
|
||||
class F(FilterSet):
|
||||
lovers = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['lovers']
|
||||
|
||||
# f = F({'lovers': 1}, queryset=qs)
|
||||
# self.assertQuerysetEqual(
|
||||
# f.qs, ["Ender's Game", "Rainbow Six"], lambda o: o.title)
|
||||
|
||||
def test_m2m_relation_attribute(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books__title']
|
||||
|
||||
qs = User.objects.all().order_by('username')
|
||||
f = F({'favorite_books__title': "Ender's Game"}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['aaron', 'alex'], lambda o: o.username)
|
||||
|
||||
f = F({'favorite_books__title': 'Rainbow Six'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
class F(FilterSet):
|
||||
favorite_books__title = MultipleChoiceFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books__title']
|
||||
|
||||
f = F()
|
||||
self.assertEqual(
|
||||
len(f.filters['favorite_books__title'].field.choices), 0)
|
||||
# f = F({'favorite_books__title': ['1', '3']},
|
||||
# queryset=qs)
|
||||
# self.assertQuerysetEqual(
|
||||
# f.qs, ['aaron', 'alex'], lambda o: o.username)
|
||||
|
||||
class F(FilterSet):
|
||||
favorite_books__title = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books__title']
|
||||
|
||||
f = F({'favorite_books__title': "Snowcrash"}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['aaron'], lambda o: o.username)
|
||||
|
||||
def test_reverse_m2m_relation_attribute(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['lovers__username']
|
||||
|
||||
qs = Book.objects.all().order_by('title')
|
||||
f = F({'lovers__username': "alex"}, queryset=qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ["Ender's Game", "Rainbow Six"], lambda o: o.title)
|
||||
|
||||
f = F({'lovers__username': 'jacob'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [], lambda o: o.title)
|
||||
|
||||
class F(FilterSet):
|
||||
lovers__username = MultipleChoiceFilter()
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['lovers__username']
|
||||
|
||||
f = F()
|
||||
self.assertEqual(
|
||||
len(f.filters['lovers__username'].field.choices), 0)
|
||||
# f = F({'lovers__username': ['1', '3']},
|
||||
# queryset=qs)
|
||||
# self.assertQuerysetEqual(
|
||||
# f.qs, ["Ender's Game", "Rainbow Six"], lambda o: o.title)
|
||||
|
||||
class F(FilterSet):
|
||||
lovers__username = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['lovers__username']
|
||||
|
||||
f = F({'lovers__username': "alex"}, queryset=qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ["Ender's Game", "Rainbow Six"], lambda o: o.title)
|
||||
|
||||
@unittest.expectedFailure
|
||||
def test_m2m_relation_multiple_attributes(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books__price',
|
||||
'favorite_books__average_rating']
|
||||
|
||||
qs = User.objects.all().order_by('username')
|
||||
f = F({'favorite_books__price': "1.00",
|
||||
'favorite_books__average_rating': 4.0},
|
||||
queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['aaron'], lambda o: o.username)
|
||||
|
||||
f = F({'favorite_books__price': "3.00",
|
||||
'favorite_books__average_rating': 4.0},
|
||||
queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [], lambda o: o.username)
|
||||
|
||||
@unittest.expectedFailure
|
||||
def test_reverse_m2m_relation_multiple_attributes(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['lovers__status', 'lovers__username']
|
||||
|
||||
qs = Book.objects.all().order_by('title')
|
||||
f = F({'lovers__status': 1, 'lovers__username': "alex"}, queryset=qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ["Ender's Game", "Rainbow Six"], lambda o: o.title)
|
||||
|
||||
f = F({'lovers__status': 1, 'lovers__username': 'jacob'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [], lambda o: o.title)
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_fk_relation_on_m2m_relation(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_fk_relation_attribute_on_m2m_relation(self):
|
||||
pass
|
||||
|
||||
|
||||
class SelfReferentialRelationshipTests(TestCase):
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_self_referential_m2m_relation(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_reverse_self_referential_m2m_relation(self):
|
||||
pass
|
||||
|
||||
|
||||
class MiscFilterSetTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
User.objects.create(username='alex', status=1)
|
||||
User.objects.create(username='jacob', status=2)
|
||||
User.objects.create(username='aaron', status=2)
|
||||
User.objects.create(username='carl', status=0)
|
||||
|
||||
def test_filtering_with_declared_filters(self):
|
||||
class F(FilterSet):
|
||||
account = CharFilter(name='username')
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['account']
|
||||
|
||||
qs = mock.MagicMock()
|
||||
f = F({'account': 'jdoe'}, queryset=qs)
|
||||
result = f.qs
|
||||
self.assertNotEqual(qs, result)
|
||||
qs.all.return_value.filter.assert_called_with(username__exact='jdoe')
|
||||
|
||||
def test_filtering_with_multiple_filters(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status', 'username']
|
||||
|
||||
qs = User.objects.all()
|
||||
|
||||
f = F({'username': 'alex', 'status': '1'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
f = F({'username': 'alex', 'status': '2'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [], lambda o: o.pk)
|
||||
|
||||
def test_filter_with_action(self):
|
||||
class F(FilterSet):
|
||||
username = CharFilter(action=lambda qs, value: (
|
||||
qs.filter(**{'username__startswith': value})))
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['username']
|
||||
|
||||
f = F({'username': 'a'}, queryset=User.objects.all())
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ['alex', 'aaron'], lambda o: o.username, False)
|
||||
|
||||
def test_filter_with_initial(self):
|
||||
class F(FilterSet):
|
||||
status = ChoiceFilter(choices=STATUS_CHOICES, initial=1)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status']
|
||||
|
||||
qs = User.objects.all()
|
||||
f = F(queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
f = F({'status': 0}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['carl'], lambda o: o.username)
|
||||
|
||||
def test_qs_count(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status']
|
||||
|
||||
qs = User.objects.all()
|
||||
f = F(queryset=qs)
|
||||
self.assertEqual(len(f.qs), 4)
|
||||
self.assertEqual(f.count(), 4)
|
||||
|
||||
f = F({'status': '0'}, queryset=qs)
|
||||
self.assertEqual(len(f.qs), 1)
|
||||
self.assertEqual(f.count(), 1)
|
||||
|
||||
f = F({'status': '1'}, queryset=qs)
|
||||
self.assertEqual(len(f.qs), 1)
|
||||
self.assertEqual(f.count(), 1)
|
||||
|
||||
f = F({'status': '2'}, queryset=qs)
|
||||
self.assertEqual(len(f.qs), 2)
|
||||
self.assertEqual(f.count(), 2)
|
||||
|
|
@ -2,37 +2,26 @@ from __future__ import absolute_import
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import mock
|
||||
import datetime
|
||||
|
||||
from django.db import models
|
||||
from django.utils import unittest
|
||||
from django.test import TestCase
|
||||
from django.utils import six
|
||||
from django.utils.timezone import now
|
||||
from django.utils import timezone
|
||||
|
||||
from django_filters.filterset import FilterSet
|
||||
from django_filters.filterset import FILTER_FOR_DBFIELD_DEFAULTS
|
||||
from django_filters.filters import AllValuesFilter
|
||||
from django_filters.filterset import get_model_field
|
||||
from django_filters.filters import CharFilter
|
||||
from django_filters.filters import ChoiceFilter
|
||||
from django_filters.filters import DateRangeFilter
|
||||
# from django_filters.filters import DateTimeFilter
|
||||
from django_filters.filters import MultipleChoiceFilter
|
||||
from django_filters.filters import NumberFilter
|
||||
from django_filters.filters import RangeFilter
|
||||
# from django_filters.widgets import LinkWidget
|
||||
from django_filters.filters import ModelMultipleChoiceFilter
|
||||
|
||||
from .models import User
|
||||
from .models import Comment
|
||||
from .models import AdminUser
|
||||
from .models import Book
|
||||
from .models import Restaurant
|
||||
from .models import Article
|
||||
from .models import NetworkSetting
|
||||
from .models import SubnetMaskField
|
||||
from .models import Company
|
||||
from .models import Location
|
||||
from .models import STATUS_CHOICES
|
||||
from .models import Account
|
||||
from .models import BankAccount
|
||||
|
||||
|
||||
class HelperMethodsTests(TestCase):
|
||||
|
@ -41,9 +30,9 @@ class HelperMethodsTests(TestCase):
|
|||
def test_get_declared_filters(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_get_model_field(self):
|
||||
pass
|
||||
result = get_model_field(User, 'unknown__name')
|
||||
self.assertIsNone(result)
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_filters_for_model(self):
|
||||
|
@ -103,21 +92,32 @@ class DbFieldDefaultFiltersTests(TestCase):
|
|||
|
||||
class FilterSetFilterForFieldTests(TestCase):
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_filter_found_for_field(self):
|
||||
pass
|
||||
f = User._meta.get_field('username')
|
||||
result = FilterSet.filter_for_field(f, 'username')
|
||||
self.assertIsInstance(result, CharFilter)
|
||||
self.assertEqual(result.name, 'username')
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_filter_not_found_for_field(self):
|
||||
pass
|
||||
f = User._meta.get_field('id')
|
||||
result = FilterSet.filter_for_field(f, 'id')
|
||||
self.assertIsNone(result)
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_filter_for_field_with_extras(self):
|
||||
pass
|
||||
f = User._meta.get_field('favorite_books')
|
||||
result = FilterSet.filter_for_field(f, 'favorite_books')
|
||||
self.assertIsInstance(result, ModelMultipleChoiceFilter)
|
||||
self.assertEqual(result.name, 'favorite_books')
|
||||
self.assertTrue('queryset' in result.extra)
|
||||
self.assertIsNotNone(result.extra['queryset'])
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_filter_for_field_with_choices(self):
|
||||
pass
|
||||
f = User._meta.get_field('status')
|
||||
result = FilterSet.filter_for_field(f, 'status')
|
||||
self.assertIsInstance(result, ChoiceFilter)
|
||||
self.assertEqual(result.name, 'status')
|
||||
self.assertTrue('choices' in result.extra)
|
||||
self.assertIsNotNone(result.extra['choices'])
|
||||
|
||||
def test_filter_for_field_that_is_subclassed(self):
|
||||
f = User._meta.get_field('first_name')
|
||||
|
@ -267,829 +267,72 @@ class FilterSetClassCreationTests(TestCase):
|
|||
|
||||
self.assertEqual(list(F.base_filters.keys()), ['ip', 'mask'])
|
||||
|
||||
|
||||
class CharFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
b1 = Book.objects.create(
|
||||
title="Ender's Game", price='1.00', average_rating=3.0)
|
||||
b2 = Book.objects.create(
|
||||
title="Rainbow Six", price='1.00', average_rating=3.0)
|
||||
b3 = Book.objects.create(
|
||||
title="Snowcrash", price='1.00', average_rating=3.0)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['title']
|
||||
|
||||
qs = Book.objects.all()
|
||||
f = F(queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [b1.pk, b2.pk, b3.pk],
|
||||
lambda o: o.pk, ordered=False)
|
||||
f = F({'title': 'Snowcrash'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [b3.pk], lambda o: o.pk)
|
||||
|
||||
|
||||
class BooleanFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
User.objects.create(username='alex', is_active=False)
|
||||
User.objects.create(username='jacob', is_active=True)
|
||||
User.objects.create(username='aaron', is_active=False)
|
||||
|
||||
def test_filterset_for_proxy_model(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['is_active']
|
||||
|
||||
qs = User.objects.all()
|
||||
|
||||
# '2' and '3' are how the field expects the data from the browser
|
||||
f = F({'is_active': '2'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['jacob'], lambda o: o.username, False)
|
||||
|
||||
f = F({'is_active': '3'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs,
|
||||
['alex', 'aaron'],
|
||||
lambda o: o.username, False)
|
||||
|
||||
f = F({'is_active': '1'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs,
|
||||
['alex', 'aaron', 'jacob'],
|
||||
lambda o: o.username, False)
|
||||
|
||||
|
||||
class ChoiceFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
User.objects.create(username='alex', status=1)
|
||||
User.objects.create(username='jacob', status=2)
|
||||
User.objects.create(username='aaron', status=2)
|
||||
User.objects.create(username='carl', status=0)
|
||||
|
||||
class F(FilterSet):
|
||||
class ProxyF(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status']
|
||||
model = AdminUser
|
||||
|
||||
f = F()
|
||||
self.assertQuerysetEqual(f.qs,
|
||||
['aaron', 'alex', 'jacob', 'carl'],
|
||||
lambda o: o.username, False)
|
||||
f = F({'status': '1'})
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username, False)
|
||||
|
||||
f = F({'status': '2'})
|
||||
self.assertQuerysetEqual(f.qs, ['jacob', 'aaron'],
|
||||
lambda o: o.username, False)
|
||||
|
||||
f = F({'status': '0'})
|
||||
self.assertQuerysetEqual(f.qs, ['carl'], lambda o: o.username, False)
|
||||
|
||||
|
||||
class MultipleChoiceFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
User.objects.create(username='alex', status=1)
|
||||
User.objects.create(username='jacob', status=2)
|
||||
User.objects.create(username='aaron', status=2)
|
||||
User.objects.create(username='carl', status=0)
|
||||
|
||||
class F(FilterSet):
|
||||
status = MultipleChoiceFilter(choices=STATUS_CHOICES)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status']
|
||||
|
||||
qs = User.objects.all().order_by('username')
|
||||
f = F(queryset=qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ['aaron', 'jacob', 'alex', 'carl'],
|
||||
lambda o: o.username, False)
|
||||
|
||||
f = F({'status': ['0']}, queryset=qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ['carl'], lambda o: o.username)
|
||||
|
||||
f = F({'status': ['0', '1']}, queryset=qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ['alex', 'carl'], lambda o: o.username)
|
||||
|
||||
f = F({'status': ['0', '1', '2']}, queryset=qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ['aaron', 'alex', 'carl', 'jacob'], lambda o: o.username)
|
||||
|
||||
|
||||
class DateFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
today = now().date()
|
||||
timestamp = now().time().replace(microsecond=0)
|
||||
last_week = today - datetime.timedelta(days=7)
|
||||
check_date = six.text_type(last_week)
|
||||
u = User.objects.create(username='alex')
|
||||
Comment.objects.create(author=u, time=timestamp, date=today)
|
||||
Comment.objects.create(author=u, time=timestamp, date=last_week)
|
||||
Comment.objects.create(author=u, time=timestamp, date=today)
|
||||
Comment.objects.create(author=u, time=timestamp, date=last_week)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['date']
|
||||
|
||||
f = F({'date': check_date}, queryset=Comment.objects.all())
|
||||
self.assertEqual(len(f.qs), 2)
|
||||
self.assertQuerysetEqual(f.qs, [2, 4], lambda o: o.pk)
|
||||
|
||||
|
||||
class TimeFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
today = now().date()
|
||||
now_time = now().time().replace(microsecond=0)
|
||||
ten_min_ago = (now() - datetime.timedelta(minutes=10))
|
||||
fixed_time = ten_min_ago.time().replace(microsecond=0)
|
||||
check_time = six.text_type(fixed_time)
|
||||
u = User.objects.create(username='alex')
|
||||
Comment.objects.create(author=u, time=now_time, date=today)
|
||||
Comment.objects.create(author=u, time=fixed_time, date=today)
|
||||
Comment.objects.create(author=u, time=now_time, date=today)
|
||||
Comment.objects.create(author=u, time=fixed_time, date=today)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['time']
|
||||
|
||||
f = F({'time': check_time}, queryset=Comment.objects.all())
|
||||
self.assertEqual(len(f.qs), 2)
|
||||
self.assertQuerysetEqual(f.qs, [2, 4], lambda o: o.pk)
|
||||
|
||||
|
||||
class DateTimeFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
now_dt = now()
|
||||
ten_min_ago = now_dt - datetime.timedelta(minutes=10)
|
||||
one_day_ago = now_dt - datetime.timedelta(days=1)
|
||||
u = User.objects.create(username='alex')
|
||||
Article.objects.create(author=u, published=now_dt)
|
||||
Article.objects.create(author=u, published=ten_min_ago)
|
||||
Article.objects.create(author=u, published=one_day_ago)
|
||||
|
||||
tz = timezone.get_current_timezone()
|
||||
# make naive, like a browser would send
|
||||
local_ten_min_ago = timezone.make_naive(ten_min_ago, tz)
|
||||
check_dt = six.text_type(local_ten_min_ago)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = ['published']
|
||||
|
||||
qs = Article.objects.all()
|
||||
f = F({'published': ten_min_ago}, queryset=qs)
|
||||
self.assertEqual(len(f.qs), 1)
|
||||
self.assertQuerysetEqual(f.qs, [2], lambda o: o.pk)
|
||||
|
||||
# this is how it would come through a browser
|
||||
f = F({'published': check_dt}, queryset=qs)
|
||||
self.assertEqual(len(f.qs), 1,
|
||||
"%s isn't matching %s when cleaned" % (check_dt, ten_min_ago))
|
||||
self.assertQuerysetEqual(f.qs, [2], lambda o: o.pk)
|
||||
|
||||
|
||||
class ModelChoiceFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
jacob = User.objects.create(username='jacob')
|
||||
date = now().date()
|
||||
time = now().time()
|
||||
Comment.objects.create(author=jacob, time=time, date=date)
|
||||
Comment.objects.create(author=alex, time=time, date=date)
|
||||
Comment.objects.create(author=jacob, time=time, date=date)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['author']
|
||||
|
||||
qs = Comment.objects.all()
|
||||
f = F({'author': jacob.pk}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [1, 3], lambda o: o.pk)
|
||||
|
||||
|
||||
class ModelMultipleChoiceFilterTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
User.objects.create(username='jacob')
|
||||
aaron = User.objects.create(username='aaron')
|
||||
b1 = Book.objects.create(title="Ender's Game", price='1.00',
|
||||
average_rating=3.0)
|
||||
b2 = Book.objects.create(title="Rainbow Six", price='1.00',
|
||||
average_rating=3.0)
|
||||
b3 = Book.objects.create(title="Snowcrash", price='1.00',
|
||||
average_rating=3.0)
|
||||
Book.objects.create(title="Stranger in a Strage Land", price='1.00',
|
||||
average_rating=3.0)
|
||||
alex.favorite_books = [b1, b2]
|
||||
aaron.favorite_books = [b1, b3]
|
||||
|
||||
def test_filtering(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books']
|
||||
|
||||
qs = User.objects.all().order_by('username')
|
||||
f = F({'favorite_books': ['1']}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['aaron', 'alex'], lambda o: o.username)
|
||||
|
||||
f = F({'favorite_books': ['1', '3']}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['aaron', 'alex'], lambda o: o.username)
|
||||
|
||||
f = F({'favorite_books': ['2']}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
f = F({'favorite_books': ['4']}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [], lambda o: o.username)
|
||||
|
||||
|
||||
class NumberFilterTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
Book.objects.create(title="Ender's Game", price='10.0',
|
||||
average_rating=4.7999999999999998)
|
||||
Book.objects.create(title="Rainbow Six", price='15.0',
|
||||
average_rating=4.5999999999999996)
|
||||
Book.objects.create(title="Snowcrash", price='20.0',
|
||||
average_rating=4.2999999999999998)
|
||||
|
||||
def test_filtering(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['price']
|
||||
|
||||
f = F({'price': 10}, queryset=Book.objects.all())
|
||||
self.assertQuerysetEqual(f.qs, ['Ender\'s Game'], lambda o: o.title)
|
||||
|
||||
def test_filtering_with_single_lookup_type(self):
|
||||
class F(FilterSet):
|
||||
price = NumberFilter(lookup_type='lt')
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['price']
|
||||
|
||||
f = F({'price': 16}, queryset=Book.objects.all().order_by('title'))
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ['Ender\'s Game', 'Rainbow Six'], lambda o: o.title)
|
||||
|
||||
def test_filtering_with_multiple_lookup_types(self):
|
||||
class F(FilterSet):
|
||||
price = NumberFilter(lookup_type=['lt', 'gt'])
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['price']
|
||||
|
||||
qs = Book.objects.all()
|
||||
f = F({'price_0': '15', 'price_1': 'lt'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['Ender\'s Game'], lambda o: o.title)
|
||||
f = F({'price_0': '15', 'price_1': 'lt'})
|
||||
self.assertQuerysetEqual(f.qs, ['Ender\'s Game'], lambda o: o.title)
|
||||
f = F({'price_0': '', 'price_1': 'lt'})
|
||||
self.assertQuerysetEqual(f.qs,
|
||||
['Ender\'s Game', 'Rainbow Six', 'Snowcrash'],
|
||||
lambda o: o.title, ordered=False)
|
||||
|
||||
class F(FilterSet):
|
||||
price = NumberFilter(lookup_type=['lt', 'gt', 'exact'])
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['price']
|
||||
|
||||
f = F({'price_0': '15'})
|
||||
self.assertQuerysetEqual(f.qs, ['Rainbow Six'], lambda o: o.title)
|
||||
|
||||
|
||||
class RangeFilterTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
Book.objects.create(title="Ender's Game", price='10.0',
|
||||
average_rating=4.7999999999999998)
|
||||
Book.objects.create(title="Rainbow Six", price='15.0',
|
||||
average_rating=4.5999999999999996)
|
||||
Book.objects.create(title="Snowcrash", price='20.0',
|
||||
average_rating=4.2999999999999998)
|
||||
|
||||
def test_filtering(self):
|
||||
class F(FilterSet):
|
||||
price = RangeFilter()
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['price']
|
||||
|
||||
qs = Book.objects.all().order_by('title')
|
||||
f = F(queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs,
|
||||
['Ender\'s Game', 'Rainbow Six', 'Snowcrash'],
|
||||
lambda o: o.title)
|
||||
f = F({'price_0': '5', 'price_1': '15'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs,
|
||||
['Ender\'s Game', 'Rainbow Six'],
|
||||
lambda o: o.title)
|
||||
|
||||
|
||||
@unittest.skip('date-range is funky')
|
||||
class DateRangeFilterTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
today = now().date()
|
||||
five_days_ago = today - datetime.timedelta(days=5)
|
||||
two_weeks_ago = today - datetime.timedelta(days=14)
|
||||
two_months_ago = today - datetime.timedelta(days=62)
|
||||
two_years_ago = today - datetime.timedelta(days=800)
|
||||
alex = User.objects.create(username='alex')
|
||||
time = now().time()
|
||||
Comment.objects.create(date=two_weeks_ago, author=alex, time=time)
|
||||
Comment.objects.create(date=two_years_ago, author=alex, time=time)
|
||||
Comment.objects.create(date=five_days_ago, author=alex, time=time)
|
||||
Comment.objects.create(date=today, author=alex, time=time)
|
||||
Comment.objects.create(date=two_months_ago, author=alex, time=time)
|
||||
|
||||
def test_filtering_for_year(self):
|
||||
class F(FilterSet):
|
||||
date = DateRangeFilter()
|
||||
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['date']
|
||||
|
||||
f = F({'date': '4'}) # this year
|
||||
self.assertQuerysetEqual(f.qs, [1, 3, 4, 5], lambda o: o.pk, False)
|
||||
|
||||
def test_filtering_for_month(self):
|
||||
class F(FilterSet):
|
||||
date = DateRangeFilter()
|
||||
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['date']
|
||||
|
||||
f = F({'date': '3'}) # this month
|
||||
self.assertQuerysetEqual(f.qs, [1, 3, 4], lambda o: o.pk, False)
|
||||
self.assertEqual(list(F.base_filters), list(ProxyF.base_filters))
|
||||
|
||||
@unittest.expectedFailure
|
||||
def test_filtering_for_week(self):
|
||||
def test_filterset_for_mti_model(self):
|
||||
class F(FilterSet):
|
||||
date = DateRangeFilter()
|
||||
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['date']
|
||||
|
||||
f = F({'date': '2'}) # this week
|
||||
self.assertQuerysetEqual(f.qs, [3, 4], lambda o: o.pk, False)
|
||||
|
||||
def test_filtering_for_today(self):
|
||||
class F(FilterSet):
|
||||
date = DateRangeFilter()
|
||||
|
||||
model = Account
|
||||
|
||||
class FtiF(FilterSet):
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['date']
|
||||
model = BankAccount
|
||||
|
||||
f = F({'date': '1'}) # today
|
||||
self.assertQuerysetEqual(f.qs, [4], lambda o: o.pk, False)
|
||||
|
||||
# it will be difficult to test for TZ related issues, where "today" means
|
||||
# different things to both user and server.
|
||||
# fails due to 'account_ptr' getting picked up
|
||||
self.assertEqual(
|
||||
list(F.base_filters) + ['amount_saved'],
|
||||
list(FtiF.base_filters))
|
||||
|
||||
|
||||
class AllValuesFilterTests(TestCase):
|
||||
|
||||
def test_filtering(self):
|
||||
User.objects.create(username='alex')
|
||||
User.objects.create(username='jacob')
|
||||
User.objects.create(username='aaron')
|
||||
class FilterSetInstantiationTests(TestCase):
|
||||
|
||||
def test_creating_instance(self):
|
||||
class F(FilterSet):
|
||||
username = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['username']
|
||||
|
||||
self.assertEqual(list(F().qs), list(User.objects.all()))
|
||||
self.assertEqual(list(F({'username': 'alex'})),
|
||||
[User.objects.get(username='alex')])
|
||||
self.assertEqual(list(F({'username': 'jose'})),
|
||||
list(User.objects.all()))
|
||||
|
||||
|
||||
class RelatedObjectTests(TestCase):
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_o2o_relation(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_reverse_o2o_relation(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_o2o_relation_attribute(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_reverse_o2o_relation_attribute(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_fk_relation(self):
|
||||
pass
|
||||
|
||||
def test_reverse_fk_relation(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
jacob = User.objects.create(username='jacob')
|
||||
date = now().date()
|
||||
time = now().time()
|
||||
Comment.objects.create(text='comment 1',
|
||||
author=jacob, time=time, date=date)
|
||||
Comment.objects.create(text='comment 2',
|
||||
author=alex, time=time, date=date)
|
||||
Comment.objects.create(text='comment 3',
|
||||
author=jacob, time=time, date=date)
|
||||
|
||||
with self.assertRaises(AttributeError):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['comments']
|
||||
|
||||
# qs = User.objects.all()
|
||||
# f = F({'comment': 2}, queryset=qs)
|
||||
# self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
with self.assertRaises(AttributeError):
|
||||
class F(FilterSet):
|
||||
comment = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['comments']
|
||||
|
||||
# f = F({'comments': 2}, queryset=qs)
|
||||
# self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
def test_fk_relation_attribute(self):
|
||||
now_dt = now()
|
||||
alex = User.objects.create(username='alex')
|
||||
jacob = User.objects.create(username='jacob')
|
||||
User.objects.create(username='aaron')
|
||||
|
||||
Article.objects.create(author=alex, published=now_dt)
|
||||
Article.objects.create(author=jacob, published=now_dt)
|
||||
Article.objects.create(author=alex, published=now_dt)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = ['author__username']
|
||||
|
||||
self.assertEqual(list(F.base_filters), ['author__username'])
|
||||
self.assertEqual(F({'author__username': 'alex'}).qs.count(), 2)
|
||||
self.assertEqual(F({'author__username': 'jacob'}).qs.count(), 1)
|
||||
|
||||
class F(FilterSet):
|
||||
author__username = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = ['author__username']
|
||||
|
||||
self.assertEqual(F({'author__username': 'alex'}).qs.count(), 2)
|
||||
|
||||
def test_reverse_fk_relation_attribute(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
jacob = User.objects.create(username='jacob')
|
||||
date = now().date()
|
||||
time = now().time()
|
||||
Comment.objects.create(text='comment 1',
|
||||
author=jacob, time=time, date=date)
|
||||
Comment.objects.create(text='comment 2',
|
||||
author=alex, time=time, date=date)
|
||||
Comment.objects.create(text='comment 3',
|
||||
author=jacob, time=time, date=date)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['comments__text']
|
||||
|
||||
qs = User.objects.all()
|
||||
f = F({'comments__text': 'comment 2'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
class F(FilterSet):
|
||||
comments__text = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['comments__text']
|
||||
|
||||
f = F({'comments__text': 'comment 2'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_m2m_relation(self):
|
||||
pass
|
||||
|
||||
def test_reverse_m2m_relation(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
User.objects.create(username='jacob')
|
||||
aaron = User.objects.create(username='aaron')
|
||||
b1 = Book.objects.create(title="Ender's Game", price='1.00',
|
||||
average_rating=3.0)
|
||||
b2 = Book.objects.create(title="Rainbow Six", price='1.00',
|
||||
average_rating=3.0)
|
||||
b3 = Book.objects.create(title="Snowcrash", price='1.00',
|
||||
average_rating=3.0)
|
||||
Book.objects.create(title="Stranger in a Strage Land", price='1.00',
|
||||
average_rating=3.0)
|
||||
alex.favorite_books = [b1, b2]
|
||||
aaron.favorite_books = [b1, b3]
|
||||
|
||||
with self.assertRaises(AttributeError):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['lovers']
|
||||
|
||||
# qs = User.objects.all()
|
||||
# f = F({'lovers': [1]}, queryset=qs)
|
||||
# self.assertQuerysetEqual(
|
||||
# f.qs, ["Ender's Game", "Rainbow Six"], lambda o: o.title)
|
||||
|
||||
with self.assertRaises(AttributeError):
|
||||
class F(FilterSet):
|
||||
lovers = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['lovers']
|
||||
|
||||
# f = F({'lovers': 1}, queryset=qs)
|
||||
# self.assertQuerysetEqual(
|
||||
# f.qs, ["Ender's Game", "Rainbow Six"], lambda o: o.title)
|
||||
|
||||
def test_m2m_relation_attribute(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
User.objects.create(username='jacob')
|
||||
aaron = User.objects.create(username='aaron')
|
||||
b1 = Book.objects.create(title="Ender's Game", price='1.00',
|
||||
average_rating=3.0)
|
||||
b2 = Book.objects.create(title="Rainbow Six", price='1.00',
|
||||
average_rating=3.0)
|
||||
b3 = Book.objects.create(title="Snowcrash", price='1.00',
|
||||
average_rating=3.0)
|
||||
Book.objects.create(title="Stranger in a Strage Land", price='1.00',
|
||||
average_rating=3.0)
|
||||
alex.favorite_books = [b1, b2]
|
||||
aaron.favorite_books = [b1, b3]
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books__title']
|
||||
|
||||
qs = User.objects.all().order_by('username')
|
||||
f = F({'favorite_books__title': "Ender's Game"}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['aaron', 'alex'], lambda o: o.username)
|
||||
|
||||
f = F({'favorite_books__title': 'Rainbow Six'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
class F(FilterSet):
|
||||
favorite_books__title = MultipleChoiceFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books__title']
|
||||
|
||||
f = F()
|
||||
self.assertEqual(
|
||||
len(f.filters['favorite_books__title'].field.choices), 0)
|
||||
# f = F({'favorite_books__title': ['1', '3']},
|
||||
# queryset=qs)
|
||||
# self.assertQuerysetEqual(
|
||||
# f.qs, ['aaron', 'alex'], lambda o: o.username)
|
||||
self.assertFalse(f.is_bound)
|
||||
self.assertIsNotNone(f.queryset)
|
||||
self.assertEqual(len(f.filters), len(F.base_filters))
|
||||
for name, filter_ in f.filters.items():
|
||||
self.assertEqual(
|
||||
filter_.model,
|
||||
User,
|
||||
"%s does not have model set correctly" % name)
|
||||
|
||||
def test_creating_bound_instance(self):
|
||||
class F(FilterSet):
|
||||
favorite_books__title = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books__title']
|
||||
|
||||
f = F({'favorite_books__title': "Snowcrash"}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['aaron'], lambda o: o.username)
|
||||
|
||||
def test_reverse_m2m_relation_attribute(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
User.objects.create(username='jacob')
|
||||
aaron = User.objects.create(username='aaron')
|
||||
b1 = Book.objects.create(title="Ender's Game", price='1.00',
|
||||
average_rating=3.0)
|
||||
b2 = Book.objects.create(title="Rainbow Six", price='1.00',
|
||||
average_rating=3.0)
|
||||
b3 = Book.objects.create(title="Snowcrash", price='1.00',
|
||||
average_rating=3.0)
|
||||
Book.objects.create(title="Stranger in a Strage Land", price='1.00',
|
||||
average_rating=3.0)
|
||||
alex.favorite_books = [b1, b2]
|
||||
aaron.favorite_books = [b1, b3]
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['lovers__username']
|
||||
|
||||
qs = Book.objects.all().order_by('title')
|
||||
f = F({'lovers__username': "alex"}, queryset=qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ["Ender's Game", "Rainbow Six"], lambda o: o.title)
|
||||
|
||||
f = F({'lovers__username': 'jacob'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [], lambda o: o.title)
|
||||
|
||||
class F(FilterSet):
|
||||
lovers__username = MultipleChoiceFilter()
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['lovers__username']
|
||||
|
||||
f = F()
|
||||
self.assertEqual(
|
||||
len(f.filters['lovers__username'].field.choices), 0)
|
||||
# f = F({'lovers__username': ['1', '3']},
|
||||
# queryset=qs)
|
||||
# self.assertQuerysetEqual(
|
||||
# f.qs, ["Ender's Game", "Rainbow Six"], lambda o: o.title)
|
||||
|
||||
class F(FilterSet):
|
||||
lovers__username = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['lovers__username']
|
||||
|
||||
f = F({'lovers__username': "alex"}, queryset=qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ["Ender's Game", "Rainbow Six"], lambda o: o.title)
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_fk_relation_on_m2m_relation(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_fk_relation_attribute_on_m2m_relation(self):
|
||||
pass
|
||||
|
||||
|
||||
class ProblematicBehaviorTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
company = Company.objects.create(name='company')
|
||||
Location.objects.create(
|
||||
company=company, open_days="some", zip_code="90210")
|
||||
Location.objects.create(
|
||||
company=company, open_days="WEEKEND", zip_code="11111")
|
||||
|
||||
@unittest.expectedFailure
|
||||
def test_related_attributes_filter_differently(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Company
|
||||
fields = ('locations__zip_code', 'locations__open_days')
|
||||
|
||||
f = F({'locations__zip_code': '90210',
|
||||
'locations__open_days': 'WEEKEND'})
|
||||
self.assertEqual(f.qs.count(), 0)
|
||||
|
||||
|
||||
class FilterSetTests(TestCase):
|
||||
|
||||
def test_filtering_with_declared_filters(self):
|
||||
class F(FilterSet):
|
||||
account = CharFilter(name='username')
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['account']
|
||||
|
||||
qs = mock.MagicMock()
|
||||
f = F({'account': 'jdoe'}, queryset=qs)
|
||||
result = f.qs
|
||||
self.assertNotEqual(qs, result)
|
||||
qs.all.return_value.filter.assert_called_with(username__exact='jdoe')
|
||||
|
||||
def test_filtering_with_multiple_filters(self):
|
||||
User.objects.create(username='alex', status=1)
|
||||
User.objects.create(username='jacob', status=2)
|
||||
User.objects.create(username='aaron', status=2)
|
||||
User.objects.create(username='carl', status=0)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status', 'username']
|
||||
|
||||
qs = User.objects.all()
|
||||
|
||||
f = F({'username': 'alex', 'status': '1'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
f = F({'username': 'alex', 'status': '2'}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, [], lambda o: o.pk)
|
||||
|
||||
def test_filter_with_action(self):
|
||||
User.objects.create(username='alex')
|
||||
User.objects.create(username='jacob')
|
||||
User.objects.create(username='aaron')
|
||||
|
||||
class F(FilterSet):
|
||||
username = CharFilter(action=lambda qs, value: (
|
||||
qs.filter(**{'username__startswith': value})))
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['username']
|
||||
|
||||
f = F({'username': 'a'}, queryset=User.objects.all())
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ['alex', 'aaron'], lambda o: o.username, False)
|
||||
|
||||
def test_filter_with_initial(self):
|
||||
User.objects.create(username='alex', status=1)
|
||||
User.objects.create(username='jacob', status=2)
|
||||
User.objects.create(username='aaron', status=2)
|
||||
User.objects.create(username='carl', status=0)
|
||||
|
||||
class F(FilterSet):
|
||||
status = ChoiceFilter(choices=STATUS_CHOICES, initial=1)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status']
|
||||
|
||||
qs = User.objects.all()
|
||||
f = F(queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username)
|
||||
|
||||
f = F({'status': 0}, queryset=qs)
|
||||
self.assertQuerysetEqual(f.qs, ['carl'], lambda o: o.username)
|
||||
|
||||
def test_qs_count(self):
|
||||
User.objects.create(username='alex', status=1)
|
||||
User.objects.create(username='jacob', status=2)
|
||||
User.objects.create(username='aaron', status=2)
|
||||
User.objects.create(username='carl', status=0)
|
||||
f = F({'username': 'username'})
|
||||
self.assertTrue(f.is_bound)
|
||||
|
||||
def test_creating_with_queryset(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status']
|
||||
fields = ['username']
|
||||
|
||||
qs = User.objects.all()
|
||||
f = F(queryset=qs)
|
||||
self.assertEqual(len(f.qs), 4)
|
||||
self.assertEqual(f.count(), 4)
|
||||
|
||||
f = F({'status': '0'}, queryset=qs)
|
||||
self.assertEqual(len(f.qs), 1)
|
||||
self.assertEqual(f.count(), 1)
|
||||
|
||||
f = F({'status': '1'}, queryset=qs)
|
||||
self.assertEqual(len(f.qs), 1)
|
||||
self.assertEqual(f.count(), 1)
|
||||
|
||||
f = F({'status': '2'}, queryset=qs)
|
||||
self.assertEqual(len(f.qs), 2)
|
||||
self.assertEqual(f.count(), 2)
|
||||
m = mock.Mock()
|
||||
f = F(queryset=m)
|
||||
self.assertEqual(f.queryset, m)
|
||||
|
||||
|
||||
class FilterSetOrdering(TestCase):
|
||||
class FilterSetOrderingTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.alex = User.objects.create(username='alex', status=1)
|
||||
|
@ -1121,6 +364,17 @@ class FilterSetOrdering(TestCase):
|
|||
self.assertQuerysetEqual(
|
||||
f.qs, ['carl', 'alex', 'jacob', 'aaron'], lambda o: o.username)
|
||||
|
||||
def test_ordering_on_unknown_value_is_ignored(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['username', 'status']
|
||||
order_by = ['status']
|
||||
|
||||
f = F({'o': 'username'}, queryset=self.qs)
|
||||
self.assertQuerysetEqual(
|
||||
f.qs, ['alex', 'jacob', 'aaron', 'carl'], lambda o: o.username)
|
||||
|
||||
def test_ordering_on_differnt_field(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
|
|
|
@ -2,26 +2,14 @@ from __future__ import absolute_import
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django import forms
|
||||
from django.utils import unittest
|
||||
from django.test import TestCase
|
||||
from django.utils import six
|
||||
from django.utils.timezone import now
|
||||
|
||||
from django_filters.filterset import FilterSet
|
||||
from django_filters.filters import AllValuesFilter
|
||||
from django_filters.filters import CharFilter
|
||||
from django_filters.filters import ChoiceFilter
|
||||
from django_filters.filters import DateRangeFilter
|
||||
from django_filters.filters import ModelChoiceFilter
|
||||
from django_filters.filters import ModelMultipleChoiceFilter
|
||||
from django_filters.filters import MultipleChoiceFilter
|
||||
from django_filters.filters import RangeFilter
|
||||
from django_filters.widgets import LinkWidget
|
||||
|
||||
from .models import User
|
||||
from .models import Comment
|
||||
from .models import Book
|
||||
from .models import Article
|
||||
from .models import STATUS_CHOICES
|
||||
|
||||
|
||||
|
@ -42,17 +30,11 @@ class FilterSetFormTests(TestCase):
|
|||
|
||||
f = F().form
|
||||
self.assertIsInstance(f, forms.Form)
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr><th><label for="id_title">Title:</label></th>
|
||||
<td>
|
||||
<input type="text" name="title" id="id_title" />
|
||||
</td>
|
||||
</tr>""")
|
||||
self.assertEqual(list(f.fields), ['title'])
|
||||
|
||||
def test_custom_form(self):
|
||||
class MyForm(forms.Form):
|
||||
def as_table(self):
|
||||
return "lol string"
|
||||
pass
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
|
@ -60,8 +42,7 @@ class FilterSetFormTests(TestCase):
|
|||
form = MyForm
|
||||
|
||||
f = F().form
|
||||
self.assertIsInstance(f, forms.Form)
|
||||
self.assertEqual(six.text_type(f), 'lol string')
|
||||
self.assertIsInstance(f, MyForm)
|
||||
|
||||
def test_form_prefix(self):
|
||||
class F(FilterSet):
|
||||
|
@ -74,12 +55,6 @@ class FilterSetFormTests(TestCase):
|
|||
|
||||
f = F(prefix='prefix').form
|
||||
self.assertEqual(f.prefix, 'prefix')
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr><th><label for="id_prefix-title">Title:</label></th>
|
||||
<td>
|
||||
<input type="text" name="prefix-title" id="id_prefix-title" />
|
||||
</td>
|
||||
</tr>""")
|
||||
|
||||
def test_form_fields(self):
|
||||
class F(FilterSet):
|
||||
|
@ -119,12 +94,8 @@ class FilterSetFormTests(TestCase):
|
|||
fields = ('title',)
|
||||
|
||||
f = F().form
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr><th><label for="id_title">Book title:</label></th>
|
||||
<td>
|
||||
<input type="text" name="title" id="id_title" />
|
||||
</td>
|
||||
</tr>""")
|
||||
self.assertEqual(f.fields['title'].label, "Book title")
|
||||
self.assertEqual(f['title'].label, 'Book title')
|
||||
|
||||
def test_form_field_with_manual_name(self):
|
||||
class F(FilterSet):
|
||||
|
@ -135,12 +106,8 @@ class FilterSetFormTests(TestCase):
|
|||
fields = ('book_title',)
|
||||
|
||||
f = F().form
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr><th><label for="id_book_title">Book title:</label></th>
|
||||
<td>
|
||||
<input type="text" name="book_title" id="id_book_title" />
|
||||
</td>
|
||||
</tr>""")
|
||||
self.assertEqual(f.fields['book_title'].label, None)
|
||||
self.assertEqual(f['book_title'].label, 'Book title')
|
||||
|
||||
def test_form_field_with_manual_name_and_label(self):
|
||||
class F(FilterSet):
|
||||
|
@ -151,12 +118,8 @@ class FilterSetFormTests(TestCase):
|
|||
fields = ('f1',)
|
||||
|
||||
f = F().form
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr><th><label for="id_f1">Book title:</label></th>
|
||||
<td>
|
||||
<input type="text" name="f1" id="id_f1" />
|
||||
</td>
|
||||
</tr>""")
|
||||
self.assertEqual(f.fields['f1'].label, "Book title")
|
||||
self.assertEqual(f['f1'].label, 'Book title')
|
||||
|
||||
def test_filter_with_initial(self):
|
||||
class F(FilterSet):
|
||||
|
@ -166,13 +129,28 @@ class FilterSetFormTests(TestCase):
|
|||
model = User
|
||||
fields = ['status']
|
||||
|
||||
f = F().form['status']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<select name="status" id="id_status">
|
||||
<option value="0">Regular</option>
|
||||
<option selected="selected" value="1">Manager</option>
|
||||
<option value="2">Admin</option>
|
||||
</select>""")
|
||||
f = F().form
|
||||
self.assertEqual(f.fields['status'].initial, 1)
|
||||
|
||||
def test_form_is_not_bound(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ('title',)
|
||||
|
||||
f = F().form
|
||||
self.assertFalse(f.is_bound)
|
||||
self.assertEqual(f.data, {})
|
||||
|
||||
def test_form_is_bound(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ('title',)
|
||||
|
||||
f = F({'title': 'Some book'}).form
|
||||
self.assertTrue(f.is_bound)
|
||||
self.assertEqual(f.data, {'title': 'Some book'})
|
||||
|
||||
def test_ordering(self):
|
||||
class F(FilterSet):
|
||||
|
@ -185,10 +163,6 @@ class FilterSetFormTests(TestCase):
|
|||
self.assertEqual(len(f.fields), 3)
|
||||
self.assertIn('o', f.fields)
|
||||
self.assertEqual(f.fields['o'].choices, [('status', 'Status')])
|
||||
self.assertHTMLEqual(six.text_type(f['o']), """
|
||||
<select id="id_o" name="o">
|
||||
<option value="status">Status</option>
|
||||
</select>""")
|
||||
|
||||
def test_ordering_uses_all_fields(self):
|
||||
class F(FilterSet):
|
||||
|
@ -200,11 +174,6 @@ class FilterSetFormTests(TestCase):
|
|||
f = F().form
|
||||
self.assertEqual(f.fields['o'].choices,
|
||||
[('username', 'Username'), ('status', 'Status')])
|
||||
self.assertHTMLEqual(six.text_type(f['o']), """
|
||||
<select id="id_o" name="o">
|
||||
<option value="username">Username</option>
|
||||
<option value="status">Status</option>
|
||||
</select>""")
|
||||
|
||||
def test_ordering_uses_filter_label(self):
|
||||
class F(FilterSet):
|
||||
|
@ -231,11 +200,6 @@ class FilterSetFormTests(TestCase):
|
|||
f = F().form
|
||||
self.assertEqual(f.fields['o'].choices,
|
||||
[('username', 'Account'), ('status', 'Status')])
|
||||
self.assertHTMLEqual(six.text_type(f['o']), """
|
||||
<select id="id_o" name="o">
|
||||
<option value="username">Account</option>
|
||||
<option value="status">Status</option>
|
||||
</select>""")
|
||||
|
||||
def test_ordering_with_overridden_field_name(self):
|
||||
"""
|
||||
|
@ -254,10 +218,6 @@ class FilterSetFormTests(TestCase):
|
|||
self.assertNotIn('o', f.fields)
|
||||
self.assertIn('order', f.fields)
|
||||
self.assertEqual(f.fields['order'].choices, [('status', 'Status')])
|
||||
self.assertHTMLEqual(six.text_type(f['order']), """
|
||||
<select id="id_order" name="order">
|
||||
<option value="status">Status</option>
|
||||
</select>""")
|
||||
|
||||
def test_ordering_with_overridden_field_name_and_using_all_fields(self):
|
||||
class F(FilterSet):
|
||||
|
@ -283,752 +243,4 @@ class FilterSetFormTests(TestCase):
|
|||
f = F().form
|
||||
self.assertEqual(
|
||||
f.fields['o'].choices, [('status', 'Current status')])
|
||||
self.assertHTMLEqual(six.text_type(f['o']), """
|
||||
<select id="id_o" name="o">
|
||||
<option value="status">Current status</option>
|
||||
</select>""")
|
||||
|
||||
|
||||
class CharFilterTests(TestCase):
|
||||
|
||||
def test_field_output(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['title']
|
||||
|
||||
f = F().form['title']
|
||||
self.assertHTMLEqual(six.text_type(f), '''
|
||||
<input type="text" name="title" id="id_title" />''')
|
||||
|
||||
|
||||
class BooleanFilterTests(TestCase):
|
||||
|
||||
def test_field_output(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['is_active']
|
||||
|
||||
f = F().form['is_active']
|
||||
self.assertHTMLEqual(six.text_type(f), '''
|
||||
<select name="is_active" id="id_is_active">
|
||||
<option selected="selected" value="1">Unknown</option>
|
||||
<option value="2">Yes</option>
|
||||
<option value="3">No</option>
|
||||
</select>''')
|
||||
|
||||
|
||||
class ChoiceFilterTests(TestCase):
|
||||
|
||||
def test_field_output(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status']
|
||||
|
||||
f = F().form['status']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<select name="status" id="id_status">
|
||||
<option value="0">Regular</option>
|
||||
<option value="1">Manager</option>
|
||||
<option value="2">Admin</option>
|
||||
</select>""")
|
||||
|
||||
def test_field_output_with_selection(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status']
|
||||
|
||||
f = F({'status': '1'}).form['status']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<select name="status" id="id_status">
|
||||
<option value="0">Regular</option>
|
||||
<option selected="selected" value="1">Manager</option>
|
||||
<option value="2">Admin</option>
|
||||
</select>""")
|
||||
|
||||
def test_field_output_with_link_widget(self):
|
||||
class F(FilterSet):
|
||||
status = ChoiceFilter(widget=LinkWidget, choices=STATUS_CHOICES)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status']
|
||||
|
||||
f = F().form['status']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<ul id="id_status">
|
||||
<li><a href="?status=0">Regular</a></li>
|
||||
<li><a href="?status=1">Manager</a></li>
|
||||
<li><a href="?status=2">Admin</a></li>
|
||||
</ul>""")
|
||||
|
||||
def test_field_output_with_link_widget_with_selection(self):
|
||||
class F(FilterSet):
|
||||
status = ChoiceFilter(widget=LinkWidget, choices=STATUS_CHOICES)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status']
|
||||
|
||||
f = F({'status': '1'}).form['status']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<ul id="id_status">
|
||||
<li><a href="?status=0">Regular</a></li>
|
||||
<li><a class="selected" href="?status=1">Manager</a></li>
|
||||
<li><a href="?status=2">Admin</a></li>
|
||||
</ul>""")
|
||||
|
||||
|
||||
class MultipleChoiceFilterTests(TestCase):
|
||||
|
||||
def test_field_output(self):
|
||||
class F(FilterSet):
|
||||
status = MultipleChoiceFilter(choices=STATUS_CHOICES)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['status']
|
||||
|
||||
f = F().form['status']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<select multiple="multiple" name="status" id="id_status">
|
||||
<option value="0">Regular</option>
|
||||
<option value="1">Manager</option>
|
||||
<option value="2">Admin</option>
|
||||
</select>""")
|
||||
|
||||
|
||||
class DateFilterTests(TestCase):
|
||||
|
||||
def test_field_output(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['date']
|
||||
|
||||
f = F().form['date']
|
||||
self.assertHTMLEqual(six.text_type(f), '''
|
||||
<input type="text" name="date" id="id_date" />''')
|
||||
|
||||
|
||||
class DateTimeFilterTests(TestCase):
|
||||
|
||||
def test_field_output(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = ['published']
|
||||
|
||||
f = F().form['published']
|
||||
self.assertHTMLEqual(six.text_type(f), '''
|
||||
<input type="text" name="published" id="id_published" />''')
|
||||
|
||||
|
||||
class TimeFilterTests(TestCase):
|
||||
|
||||
def test_field_output(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['time']
|
||||
|
||||
f = F().form['time']
|
||||
self.assertHTMLEqual(six.text_type(f), '''
|
||||
<input type="text" name="time" id="id_time" />''')
|
||||
|
||||
|
||||
class ModelChoiceFilterTests(TestCase):
|
||||
|
||||
def test_field_output(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['author']
|
||||
|
||||
f = F().form['author']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<select name="author" id="id_author">
|
||||
<option selected="selected" value="">---------</option>
|
||||
</select>""")
|
||||
|
||||
def test_field_output_with_exising_objects(self):
|
||||
User.objects.create(username='alex')
|
||||
User.objects.create(username='jacob')
|
||||
User.objects.create(username='aaron')
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['author']
|
||||
|
||||
f = F().form['author']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<select name="author" id="id_author">
|
||||
<option selected="selected" value="">---------</option>
|
||||
<option value="1">alex</option>
|
||||
<option value="2">jacob</option>
|
||||
<option value="3">aaron</option>
|
||||
</select>""")
|
||||
|
||||
def test_field_output_with_link_widget(self):
|
||||
User.objects.create(username='alex')
|
||||
User.objects.create(username='jacob')
|
||||
User.objects.create(username='aaron')
|
||||
|
||||
class F(FilterSet):
|
||||
author = ModelChoiceFilter(
|
||||
widget=LinkWidget, queryset=User.objects.all())
|
||||
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['author']
|
||||
|
||||
f = F().form['author']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<ul id="id_author">
|
||||
<li><a class="selected" href="?author=">All</a></li>
|
||||
<li><a href="?author=1">alex</a></li>
|
||||
<li><a href="?author=2">jacob</a></li>
|
||||
<li><a href="?author=3">aaron</a></li>
|
||||
</ul>""")
|
||||
|
||||
|
||||
class ModelMultipleChoiceFilterTests(TestCase):
|
||||
|
||||
def test_field_output(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books']
|
||||
|
||||
f = F().form['favorite_books']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<select multiple="multiple"
|
||||
name="favorite_books"
|
||||
id="id_favorite_books" />""")
|
||||
|
||||
def test_field_output_with_exising_objects(self):
|
||||
Book.objects.create(
|
||||
title="Ender's Game", price='1.00', average_rating=3.0)
|
||||
Book.objects.create(
|
||||
title="Rainbow Six", price='1.00', average_rating=3.0)
|
||||
Book.objects.create(
|
||||
title="Snowcrash", price='1.00', average_rating=3.0)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books']
|
||||
|
||||
f = F().form['favorite_books']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<select multiple="multiple"
|
||||
name="favorite_books" id="id_favorite_books">
|
||||
<option value="1">Ender&39;s Game</option>
|
||||
<option value="2">Rainbow Six</option>
|
||||
<option value="3">Snowcrash</option>
|
||||
</select>""")
|
||||
|
||||
def test_field_output_with_link_widget(self):
|
||||
Book.objects.create(
|
||||
title="Ender's Game", price='1.00', average_rating=3.0)
|
||||
Book.objects.create(
|
||||
title="Rainbow Six", price='1.00', average_rating=3.0)
|
||||
Book.objects.create(
|
||||
title="Snowcrash", price='1.00', average_rating=3.0)
|
||||
|
||||
class F(FilterSet):
|
||||
favorite_books = ModelMultipleChoiceFilter(
|
||||
widget=LinkWidget, queryset=Book.objects.all())
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books']
|
||||
|
||||
f = F().form['favorite_books']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<ul id="id_favorite_books">
|
||||
<li><a href="?favorite_books=1">Ender's Game</a></li>
|
||||
<li><a href="?favorite_books=2">Rainbow Six</a></li>
|
||||
<li><a href="?favorite_books=3">Snowcrash</a></li>
|
||||
</ul>""")
|
||||
|
||||
|
||||
class NumberFilterTests(TestCase):
|
||||
|
||||
def test_field_output(self):
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['price']
|
||||
|
||||
f = F().form['price']
|
||||
self.assertHTMLEqual(six.text_type(f), '''
|
||||
<input type="text" name="price" id="id_price" />''')
|
||||
|
||||
|
||||
class RangeFilterTests(TestCase):
|
||||
|
||||
def test_field_output(self):
|
||||
class F(FilterSet):
|
||||
price = RangeFilter()
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['price']
|
||||
|
||||
f = F().form['price']
|
||||
self.assertHTMLEqual(six.text_type(f), '''
|
||||
<input type="text" name="price_0" id="id_price_0" />
|
||||
-
|
||||
<input type="text" name="price_1" id="id_price_1" />''')
|
||||
|
||||
|
||||
class DateRangeFilterTests(TestCase):
|
||||
|
||||
def test_field_output(self):
|
||||
class F(FilterSet):
|
||||
date = DateRangeFilter()
|
||||
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['date']
|
||||
|
||||
f = F().form['date']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<select name="date" id="id_date">
|
||||
<option selected="selected" value="">Any Date</option>
|
||||
<option value="1">Today</option>
|
||||
<option value="2">Past 7 days</option>
|
||||
<option value="3">This month</option>
|
||||
<option value="4">This year</option>
|
||||
</select>""")
|
||||
|
||||
def test_field_output_with_link_widget(self):
|
||||
class F(FilterSet):
|
||||
date = DateRangeFilter(widget=LinkWidget)
|
||||
|
||||
class Meta:
|
||||
model = Comment
|
||||
fields = ['date']
|
||||
|
||||
f = F()
|
||||
self.assertHTMLEqual(six.text_type(f.form), """
|
||||
<tr><th><label for="id_date">Date:</label></th>
|
||||
<td>
|
||||
<ul id="id_date">
|
||||
<li><a class="selected" href="?date=">Any Date</a></li>
|
||||
<li><a href="?date=1">Today</a></li>
|
||||
<li><a href="?date=2">Past 7 days</a></li>
|
||||
<li><a href="?date=3">This month</a></li>
|
||||
<li><a href="?date=4">This year</a></li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>""")
|
||||
|
||||
|
||||
class AllValuesFilterTests(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
User.objects.create(username='alex')
|
||||
User.objects.create(username='jacob')
|
||||
User.objects.create(username='aaron')
|
||||
|
||||
def test_field_output(self):
|
||||
class F(FilterSet):
|
||||
username = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['username']
|
||||
|
||||
f = F().form['username']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<select name="username" id="id_username">
|
||||
<option value="aaron">aaron</option>
|
||||
<option value="alex">alex</option>
|
||||
<option value="jacob">jacob</option>
|
||||
</select>""")
|
||||
|
||||
def test_field_output_with_link_widget(self):
|
||||
class F(FilterSet):
|
||||
username = AllValuesFilter(widget=LinkWidget)
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['username']
|
||||
|
||||
f = F().form['username']
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<ul id="id_username">
|
||||
<li><a href="?username=aaron">aaron</a></li>
|
||||
<li><a href="?username=alex">alex</a></li>
|
||||
<li><a href="?username=jacob">jacob</a></li>
|
||||
</ul>""")
|
||||
|
||||
|
||||
class RelatedObjectTests(TestCase):
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_o2o_relation(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_reverse_o2o_relation(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_o2o_relation_attribute(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_reverse_o2o_relation_attribute(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_fk_relation(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_reverse_fk_relation(self):
|
||||
pass
|
||||
|
||||
def test_fk_relation_attribute(self):
|
||||
now_dt = now()
|
||||
alex = User.objects.create(username='alex')
|
||||
jacob = User.objects.create(username='jacob')
|
||||
User.objects.create(username='aaron')
|
||||
|
||||
Article.objects.create(author=alex, published=now_dt)
|
||||
Article.objects.create(author=jacob, published=now_dt)
|
||||
Article.objects.create(author=alex, published=now_dt)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = ['author__username']
|
||||
|
||||
f = F().form
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr><th><label for="id_author__username">Username:</label></th>
|
||||
<td>
|
||||
<input type="text" name="author__username"
|
||||
id="id_author__username" />
|
||||
</td>
|
||||
</tr>""")
|
||||
|
||||
class F(FilterSet):
|
||||
author__username = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = Article
|
||||
fields = ['author__username']
|
||||
|
||||
f = F().form
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr>
|
||||
<th>
|
||||
<label for="id_author__username">Author username:</label>
|
||||
</th>
|
||||
<td>
|
||||
<select name="author__username" id="id_author__username">
|
||||
<option value="alex">alex</option>
|
||||
<option value="jacob">jacob</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>""")
|
||||
|
||||
def test_reverse_fk_relation_attribute(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
jacob = User.objects.create(username='jacob')
|
||||
date = now().date()
|
||||
time = now().time()
|
||||
Comment.objects.create(text='comment 1',
|
||||
author=jacob, time=time, date=date)
|
||||
Comment.objects.create(text='comment 2',
|
||||
author=alex, time=time, date=date)
|
||||
Comment.objects.create(text='comment 3',
|
||||
author=jacob, time=time, date=date)
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['comments__text']
|
||||
|
||||
f = F().form
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr><th><label for="id_comments__text">Text:</label></th>
|
||||
<td>
|
||||
<input type="text" name="comments__text"
|
||||
id="id_comments__text" />
|
||||
</td>
|
||||
</tr>""")
|
||||
|
||||
class F(FilterSet):
|
||||
comments__text = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['comments__text']
|
||||
|
||||
f = F().form
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr>
|
||||
<th>
|
||||
<label for="id_comments__text">Comments text:</label>
|
||||
</th>
|
||||
<td>
|
||||
<select name="comments__text" id="id_comments__text">
|
||||
<option value="comment 1">comment 1</option>
|
||||
<option value="comment 2">comment 2</option>
|
||||
<option value="comment 3">comment 3</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>""")
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_m2m_relation(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_reverse_m2m_relation(self):
|
||||
pass
|
||||
|
||||
def test_m2m_relation_attribute(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
User.objects.create(username='jacob')
|
||||
aaron = User.objects.create(username='aaron')
|
||||
b1 = Book.objects.create(title="Ender's Game", price='1.00',
|
||||
average_rating=3.0)
|
||||
b2 = Book.objects.create(title="Rainbow Six", price='1.00',
|
||||
average_rating=3.0)
|
||||
b3 = Book.objects.create(title="Snowcrash", price='1.00',
|
||||
average_rating=3.0)
|
||||
alex.favorite_books = [b1, b2]
|
||||
aaron.favorite_books = [b1, b3]
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books__title']
|
||||
|
||||
f = F().form
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr><th><label for="id_favorite_books__title">Title:</label></th>
|
||||
<td>
|
||||
<input type="text" name="favorite_books__title"
|
||||
id="id_favorite_books__title" />
|
||||
</td>
|
||||
</tr>""")
|
||||
|
||||
class F(FilterSet):
|
||||
favorite_books__title = MultipleChoiceFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books__title']
|
||||
|
||||
f = F().form
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr><th>
|
||||
<label for="id_favorite_books__title">
|
||||
Favorite books title:
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<select multiple="multiple" name="favorite_books__title"
|
||||
id="id_favorite_books__title" />
|
||||
</td>
|
||||
</tr>""")
|
||||
|
||||
class F(FilterSet):
|
||||
favorite_books__title = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['favorite_books__title']
|
||||
|
||||
f = F().form
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr><th>
|
||||
<label for="id_favorite_books__title">
|
||||
Favorite books title:
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<select name="favorite_books__title" id="id_favorite_books__title">
|
||||
<option value="None">None</option>
|
||||
<option value="Ender's Game">Ender&39;s Game</option>
|
||||
<option value="Rainbow Six">Rainbow Six</option>
|
||||
<option value="Snowcrash">Snowcrash</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>""")
|
||||
|
||||
def test_reverse_m2m_relation_attribute(self):
|
||||
alex = User.objects.create(username='alex')
|
||||
User.objects.create(username='jacob')
|
||||
aaron = User.objects.create(username='aaron')
|
||||
b1 = Book.objects.create(title="Ender's Game", price='1.00',
|
||||
average_rating=3.0)
|
||||
b2 = Book.objects.create(title="Rainbow Six", price='1.00',
|
||||
average_rating=3.0)
|
||||
b3 = Book.objects.create(title="Snowcrash", price='1.00',
|
||||
average_rating=3.0)
|
||||
alex.favorite_books = [b1, b2]
|
||||
aaron.favorite_books = [b1, b3]
|
||||
|
||||
class F(FilterSet):
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['lovers__username']
|
||||
|
||||
f = F().form
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr><th>
|
||||
<label for="id_lovers__username">
|
||||
Username:
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<input type="text" name="lovers__username"
|
||||
id="id_lovers__username" />
|
||||
</td>
|
||||
</tr>""")
|
||||
|
||||
class F(FilterSet):
|
||||
lovers__username = AllValuesFilter()
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['lovers__username']
|
||||
|
||||
f = F().form
|
||||
self.assertHTMLEqual(six.text_type(f), """
|
||||
<tr><th>
|
||||
<label for="id_lovers__username">
|
||||
Lovers username:
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<select name="lovers__username" id="id_lovers__username">
|
||||
<option value="aaron">aaron</option>
|
||||
<option value="alex">alex</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>""")
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_fk_relation_on_m2m_relation(self):
|
||||
pass
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_fk_relation_attribute_on_m2m_relation(self):
|
||||
pass
|
||||
|
||||
|
||||
class LookupTypesFilterTests(TestCase):
|
||||
|
||||
def test_field_output_with_multiple_lookup_types(self):
|
||||
class F(FilterSet):
|
||||
title = CharFilter(lookup_type=('istartswith', 'iendswith'))
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['title']
|
||||
|
||||
f = F().form['title']
|
||||
self.assertHTMLEqual(six.text_type(f), '''
|
||||
<input type="text" name="title_0" id="id_title_0" />
|
||||
<select name="title_1" id="id_title_1">
|
||||
<option value="iendswith">iendswith</option>
|
||||
<option value="istartswith">istartswith</option>
|
||||
</select>''')
|
||||
|
||||
@unittest.skip('todo')
|
||||
def test_field_output_with_multiple_labeled_lookup_types(self):
|
||||
class F(FilterSet):
|
||||
title = CharFilter(lookup_type=(
|
||||
('istartswith', 'Ends with'),
|
||||
('iendswith', 'Starts with'),
|
||||
))
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['title']
|
||||
|
||||
f = F().form['title']
|
||||
self.assertHTMLEqual(six.text_type(f), '''
|
||||
<input type="text" name="title_0" id="id_title_0" />
|
||||
<select name="title_1" id="id_title_1">
|
||||
<option value="iendswith">Ends with</option>
|
||||
<option value="istartswith">Starts with</option>
|
||||
</select>''')
|
||||
|
||||
def test_field_output_with_all_lookup_types(self):
|
||||
class F(FilterSet):
|
||||
title = CharFilter(lookup_type=None)
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['title']
|
||||
|
||||
f = F().form['title']
|
||||
self.assertHTMLEqual(six.text_type(f), '''
|
||||
<input type="text" name="title_0" id="id_title_0" />
|
||||
<select name="title_1" id="id_title_1">
|
||||
<option value="contains">contains</option>
|
||||
<option value="day">day</option>
|
||||
<option value="endswith">endswith</option>
|
||||
<option value="exact">exact</option>
|
||||
<option value="gt">gt</option>
|
||||
<option value="gte">gte</option>
|
||||
<option value="icontains">icontains</option>
|
||||
<option value="iendswith">iendswith</option>
|
||||
<option value="iexact">iexact</option>
|
||||
<option value="in">in</option>
|
||||
<option value="iregex">iregex</option>
|
||||
<option value="isnull">isnull</option>
|
||||
<option value="istartswith">istartswith</option>
|
||||
<option value="lt">lt</option>
|
||||
<option value="lte">lte</option>
|
||||
<option value="month">month</option>
|
||||
<option value="range">range</option>
|
||||
<option value="regex">regex</option>
|
||||
<option value="search">search</option>
|
||||
<option value="startswith">startswith</option>
|
||||
<option value="week_day">week_day</option>
|
||||
<option value="year">year</option>
|
||||
</select>''')
|
||||
|
||||
@unittest.expectedFailure
|
||||
def test_field_output_only_shows_valid_lookup_types(self):
|
||||
class F(FilterSet):
|
||||
title = CharFilter(lookup_type=True)
|
||||
|
||||
class Meta:
|
||||
model = Book
|
||||
fields = ['title']
|
||||
|
||||
f = F().form['title']
|
||||
self.assertHTMLEqual(six.text_type(f), '''
|
||||
<input type="text" name="title_0" id="id_title_0" />
|
||||
<select name="title_1" id="id_title_1">
|
||||
<option value="contains">contains</option>
|
||||
<option value="endswith">endswith</option>
|
||||
<option value="exact">exact</option>
|
||||
<option value="icontains">icontains</option>
|
||||
<option value="iendswith">iendswith</option>
|
||||
<option value="iexact">iexact</option>
|
||||
<option value="in">in</option>
|
||||
<option value="iregex">iregex</option>
|
||||
<option value="isnull">isnull</option>
|
||||
<option value="istartswith">istartswith</option>
|
||||
<option value="regex">regex</option>
|
||||
<option value="search">search</option>
|
||||
<option value="startswith">startswith</option>
|
||||
</select>''')
|
||||
|
||||
|
|
|
@ -53,6 +53,14 @@ class User(models.Model):
|
|||
return self.username
|
||||
|
||||
|
||||
class AdminUser(User):
|
||||
class Meta:
|
||||
proxy = True
|
||||
|
||||
def __unicode__(self):
|
||||
return "%s (ADMIN)" % self.username
|
||||
|
||||
|
||||
class Comment(models.Model):
|
||||
text = models.TextField()
|
||||
author = models.ForeignKey(User, related_name='comments')
|
||||
|
@ -113,3 +121,19 @@ class Location(models.Model):
|
|||
def __unicode__(self):
|
||||
return '%s: %s' % (self.company.name, self.name)
|
||||
|
||||
|
||||
class Account(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
in_good_standing = models.BooleanField()
|
||||
friendly = models.BooleanField()
|
||||
|
||||
|
||||
class Profile(models.Model):
|
||||
account = models.OneToOneField(Account, related_name='profile')
|
||||
likes_coffee = models.BooleanField()
|
||||
likes_tea = models.BooleanField()
|
||||
|
||||
|
||||
class BankAccount(Account):
|
||||
amount_saved = models.IntegerField(default=0)
|
||||
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
from __future__ import absolute_import
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from django_filters.views import FilterView
|
||||
from django_filters.filterset import FilterSet, filterset_factory
|
||||
|
||||
from .models import Book
|
||||
|
||||
|
@ -32,6 +37,33 @@ class GenericClassBasedViewTests(GenericViewTestCase):
|
|||
self.assertNotContains(response, b)
|
||||
self.assertContains(response, 'Snowcrash')
|
||||
|
||||
def test_view_with_filterset_not_model(self):
|
||||
factory = RequestFactory()
|
||||
request = factory.get(self.base_url)
|
||||
filterset = filterset_factory(Book)
|
||||
view = FilterView.as_view(filterset_class=filterset)
|
||||
response = view(request)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
for b in ['Ender's Game', 'Rainbow Six', 'Snowcrash']:
|
||||
self.assertContains(response, b)
|
||||
|
||||
def test_view_without_filterset_or_model(self):
|
||||
factory = RequestFactory()
|
||||
request = factory.get(self.base_url)
|
||||
view = FilterView.as_view()
|
||||
with self.assertRaises(ImproperlyConfigured):
|
||||
view(request)
|
||||
|
||||
def test_view_with_bad_filterset(self):
|
||||
class MyFilterSet(FilterSet):
|
||||
pass
|
||||
|
||||
factory = RequestFactory()
|
||||
request = factory.get(self.base_url)
|
||||
view = FilterView.as_view(filterset_class=MyFilterSet)
|
||||
with self.assertRaises(ImproperlyConfigured):
|
||||
view(request)
|
||||
|
||||
|
||||
class GenericFunctionalViewTests(GenericViewTestCase):
|
||||
base_url = '/books-legacy/'
|
||||
|
|
|
@ -2,6 +2,7 @@ from __future__ import absolute_import
|
|||
from __future__ import unicode_literals
|
||||
|
||||
from django.test import TestCase
|
||||
from django.forms import TextInput, Select
|
||||
|
||||
from django_filters.widgets import RangeWidget
|
||||
from django_filters.widgets import LinkWidget
|
||||
|
@ -14,6 +15,30 @@ class LookupTypeWidgetTests(TestCase):
|
|||
with self.assertRaises(TypeError):
|
||||
LookupTypeWidget()
|
||||
|
||||
def test_widget_render(self):
|
||||
widgets = [TextInput(), Select(choices=(('a', 'a'), ('b', 'b')))]
|
||||
w = LookupTypeWidget(widgets)
|
||||
self.assertHTMLEqual(w.render('price', ''), """
|
||||
<input name="price_0" type="text" />
|
||||
<select name="price_1">
|
||||
<option value="a">a</option>
|
||||
<option value="b">b</option>
|
||||
</select>""")
|
||||
|
||||
self.assertHTMLEqual(w.render('price', None), """
|
||||
<input name="price_0" type="text" />
|
||||
<select name="price_1">
|
||||
<option value="a">a</option>
|
||||
<option value="b">b</option>
|
||||
</select>""")
|
||||
|
||||
self.assertHTMLEqual(w.render('price', ['2', 'a']), """
|
||||
<input name="price_0" type="text" value="2" />
|
||||
<select name="price_1">
|
||||
<option selected="selected" value="a">a</option>
|
||||
<option value="b">b</option>
|
||||
</select>""")
|
||||
|
||||
|
||||
class LinkWidgetTests(TestCase):
|
||||
|
||||
|
@ -35,6 +60,12 @@ class LinkWidgetTests(TestCase):
|
|||
<li><a href="?price=test-val2">test-label2</a></li>
|
||||
</ul>""")
|
||||
|
||||
self.assertHTMLEqual(w.render('price', None), """
|
||||
<ul>
|
||||
<li><a href="?price=test-val1">test-label1</a></li>
|
||||
<li><a href="?price=test-val2">test-label2</a></li>
|
||||
</ul>""")
|
||||
|
||||
self.assertHTMLEqual(w.render('price', 'test-val1'), """
|
||||
<ul>
|
||||
<li><a class="selected"
|
||||
|
@ -42,6 +73,52 @@ class LinkWidgetTests(TestCase):
|
|||
<li><a href="?price=test-val2">test-label2</a></li>
|
||||
</ul>""")
|
||||
|
||||
def test_widget_with_option_groups(self):
|
||||
choices = (
|
||||
('Audio', (
|
||||
('vinyl', 'Vinyl'),
|
||||
('cd', 'CD'),
|
||||
)
|
||||
),
|
||||
('Video', (
|
||||
('vhs', 'VHS Tape'),
|
||||
('dvd', 'DVD'),
|
||||
)
|
||||
),
|
||||
('unknown', 'Unknown'),
|
||||
)
|
||||
|
||||
w = LinkWidget(choices=choices)
|
||||
self.assertHTMLEqual(w.render('media', ''), """
|
||||
<ul>
|
||||
<li><a href="?media=vinyl">Vinyl</a></li>
|
||||
<li><a href="?media=cd">CD</a></li>
|
||||
<li><a href="?media=vhs">VHS Tape</a></li>
|
||||
<li><a href="?media=dvd">DVD</a></li>
|
||||
<li><a href="?media=unknown">Unknown</a></li>
|
||||
</ul>""")
|
||||
|
||||
def test_widget_with_blank_choice(self):
|
||||
choices = (
|
||||
('', '---------'),
|
||||
('test-val1', 'test-label1'),
|
||||
('test-val2', 'test-label2'),
|
||||
)
|
||||
|
||||
w = LinkWidget(choices=choices)
|
||||
self.assertHTMLEqual(w.render('price', ''), """
|
||||
<ul>
|
||||
<li><a class="selected" href="?price=">All</a></li>
|
||||
<li><a href="?price=test-val1">test-label1</a></li>
|
||||
<li><a href="?price=test-val2">test-label2</a></li>
|
||||
</ul>""")
|
||||
|
||||
def test_widget_value_from_datadict(self):
|
||||
w = LinkWidget()
|
||||
data = {'price': 'test-val1'}
|
||||
result = w.value_from_datadict(data, {}, 'price')
|
||||
self.assertEqual(result, 'test-val1')
|
||||
|
||||
|
||||
class RangeWidgetTests(TestCase):
|
||||
|
||||
|
|
Loading…
Reference in New Issue