Skip to content

Commit

Permalink
Merge pull request #213 from alex/develop
Browse files Browse the repository at this point in the history
Version 0.9.2 Release
  • Loading branch information
Carlton Gibson committed Jan 23, 2015
2 parents 2876348 + 13d4fe3 commit 11ee90a
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.9.1
current_version = 0.9.2
commit = False
tag = False
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?
Expand Down
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
Version 0.9.2 (2015-01-23)
--------------------------

* FIXED: Compatibility with Django v1.8a1

Version 0.9.1 (2014-12-03)
--------------------------

Expand Down
2 changes: 1 addition & 1 deletion django_filters/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from .filterset import FilterSet
from .filters import *

__version__ = '0.9.1'
__version__ = '0.9.2'


def parse_version(version):
Expand Down
15 changes: 10 additions & 5 deletions django_filters/filterset.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from django.core.validators import EMPTY_VALUES
from django.db import models
from django.db.models.fields import FieldDoesNotExist
from django.db.models.related import RelatedObject
from django.utils import six
from django.utils.text import capfirst
from django.utils.translation import ugettext as _
Expand All @@ -26,6 +25,12 @@
# Django < 1.5 fallback
from django.utils.datastructures import SortedDict as OrderedDict # noqa

try:
from django.db.models.related import RelatedObject as ForeignObjectRel
except ImportError: # pragma: nocover
# Django >= 1.8 replaces RelatedObject with ForeignObjectRel
from django.db.models.fields.related import ForeignObjectRel


from .filters import (Filter, CharFilter, BooleanFilter,
ChoiceFilter, DateFilter, DateTimeFilter, TimeFilter, ModelChoiceFilter,
Expand Down Expand Up @@ -73,7 +78,7 @@ def get_model_field(model, f):
rel = opts.get_field_by_name(name)[0]
except FieldDoesNotExist:
return None
if isinstance(rel, RelatedObject):
if isinstance(rel, ForeignObjectRel):
model = rel.model
opts = rel.opts
else:
Expand Down Expand Up @@ -103,7 +108,7 @@ def filters_for_model(model, fields=None, exclude=None, filter_for_field=None,
if field is None:
field_dict[f] = None
continue
if isinstance(field, RelatedObject):
if isinstance(field, ForeignObjectRel):
filter_ = filter_for_reverse_field(field, f)
if filter_:
field_dict[f] = filter_
Expand Down Expand Up @@ -378,7 +383,7 @@ def get_ordering_field(self):
(fltr.name or f, fltr.label or capfirst(f)),
("-%s" % (fltr.name or f), _('%s (descending)' % (fltr.label or capfirst(f))))
])
return forms.ChoiceField(label="Ordering", required=False,
return forms.ChoiceField(label=_("Ordering"), required=False,
choices=choices)

@property
Expand Down Expand Up @@ -426,7 +431,7 @@ def filter_for_field(cls, f, name, lookup_type='exact'):
@classmethod
def filter_for_reverse_field(cls, f, name):
rel = f.field.rel
queryset = f.model._default_manager.all()
queryset = f.field.model._default_manager.all()
default = {
'name': name,
'label': capfirst(rel.related_name),
Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@
# built documents.
#
# The short X.Y version.
version = '0.9.1'
version = '0.9.2'
# The full version, including alpha/beta/rc tags.
release = '0.9.1'
release = '0.9.2'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
24 changes: 24 additions & 0 deletions docs/ref/filters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,30 @@ This filter matches a boolean, either ``True`` or ``False``, used with
This filter matches an item of any type by choices, used with any field that
has ``choices``.


Requires ``choices`` ``kwarg`` to be passed if explicitly declared on the ``FilterSet``. For example::

class User(models.Model):
username = models.CharField(max_length=255)
first_name = SubCharField(max_length=100)
last_name = SubSubCharField(max_length=100)

status = models.IntegerField(choices=STATUS_CHOICES, default=0)

STATUS_CHOICES = (
(0, 'Regular'),
(1, 'Manager'),
(2, 'Admin'),
)

class F(FilterSet):
status = ChoiceFilter(choices=STATUS_CHOICES)
class Meta:
model = User
fields = ['status']



``TypedChoiceFilter``
~~~~~~~~~~~~~~~~~~~~~

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

setup(
name='django-filter',
version='0.9.1',
version='0.9.2',
description=('Django-filter is a reusable Django application for allowing'
' users to filter querysets dynamically.'),
long_description=readme,
Expand Down
33 changes: 33 additions & 0 deletions tests/test_filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,39 @@ class Meta:
self.assertQuerysetEqual(f.qs, ['carl'], lambda o: o.username, False)


def test_filtering_on_explicitly_defined_field(self):
"""
Test for #30.
If you explicitly declare ChoiceFilter fields you **MUST** pass `choices`.
"""
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)
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):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def test_view(self):
for b in ['Ender&#39;s Game', 'Rainbow Six', 'Snowcrash']:
self.assertContains(response, b)

def test_view_filtering_on_price(self):
def test_view_filtering_on_title(self):
response = self.client.get(self.base_url + '?title=Snowcrash')
for b in ['Ender&#39;s Game', 'Rainbow Six']:
self.assertNotContains(response, b)
Expand Down

0 comments on commit 11ee90a

Please sign in to comment.