django-filter-0.11.0/0000755000076500000240000000000012563340512015104 5ustar carltonstaff00000000000000django-filter-0.11.0/AUTHORS0000644000076500000240000000051112524657704016164 0ustar carltonstaff00000000000000Authors ======= Thanks to the following people for contributing to django-filter. Ben Firshman Alex Gaynor Jannis Leidel Martin Mahner Brian Rosner Adam Vandenberg Florian Apolloner Andrew Ball Tino de Bruijn Maximillian Dornseif Marc Fargas Vladimir Sidorenko Tom Christie Remco Wendt Axel Haustant Brad Erickson Diogo Laginhadjango-filter-0.11.0/CHANGES.rst0000644000076500000240000000533012563340337016714 0ustar carltonstaff00000000000000Version 0.11.0 (2015-08-14) --------------------------- * FEATURE: Added default filter method lookup for MethodFilter #222 * FEATURE: Added support for yesterday in daterangefilter #234 * FEATURE: Created Filter for NumericRange. #236 * FEATURE: Added Date/time range filters #215 * FEATURE: Added option to raise with `strict` #255 * FEATURE: Added Form Field and Filter to parse ISO-8601 timestamps Version 0.10.0 (2015-05-13) --------------------- * FEATURE: Added ``conjoined`` parameter to ``MultipleChoiceFilter`` * FEATURE: Added ``together`` meta option to validate fields as a group * FIXED: Added testing on Django 1.8 * FIXED: ``get_model_field`` on Django 1.8 Version 0.9.2 (2015-01-23) -------------------------- * FIXED: Compatibility with Django v1.8a1 Version 0.9.1 (2014-12-03) -------------------------- * FIXED: Compatibility with Debug Toolbar's versions panel Version 0.9 (2014-11-28) ------------------------ * FEATURE: Allow Min/Max-Only use of RangeFilter * FEATURE: Added TypedChoiceFilter * FIXED: Correct logic for short circuit on MultipleChoiceFilter Added `always_filter` attribute and `is_noop()` test to apply short-circuiting. Set `always_filter` to `False` on init to apply default `is_noop()` test. Override `is_noop()` for more complex cases. * MISC: Version bumping with ``bumpversion`` Version 0.8 (2014-09-29) ------------------------ * FEATURE: Added exclusion filters support * FEATURE: Added `fields` dictionary shorthand syntax * FEATURE: Added `MethodFilter`. * FIXED: #115 "filters.Filter.filter() fails if it receives [] or () as value" * MISC: Various Documentation and Testing improvements Version 0.7 (2013-08-10) ------------------------ * FEATURE: Added support for AutoField. * FEATURE: There is a "distinct" flag to ensure that only unique rows are returned. * FEATURE: Support descending ordering (slighty backwards incompatible). * FEATURE: Support "strict" querysets, ie wrong filter data returns no results. * FIXED: Some translation strings were changed to be in line with admin. * FIXED: Support for Django 1.7. Version 0.6 (2013-03-25) ------------------------ * raised minimum Django version to 1.4.x * added Python 3.2 and Python 3.3 support * added Django 1.5 support and initial 1.6 compatability * FEATURE: recognition of custom model field subclasses * FEATURE: allow optional display names for order_by values * FEATURE: addition of class-based FilterView * FEATURE: addition of count() method on FilterSet to prevent pagination from loading entire queryset * FIXED: attempts to filter on reverse side of m2m, o2o or fk would raise an error Version 0.5.4 (2012-11-16) -------------------------- * project brought back to life django-filter-0.11.0/django_filter.egg-info/0000755000076500000240000000000012563340512021405 5ustar carltonstaff00000000000000django-filter-0.11.0/django_filter.egg-info/dependency_links.txt0000644000076500000240000000000112563340500025450 0ustar carltonstaff00000000000000 django-filter-0.11.0/django_filter.egg-info/not-zip-safe0000644000076500000240000000000112412210143023620 0ustar carltonstaff00000000000000 django-filter-0.11.0/django_filter.egg-info/PKG-INFO0000644000076500000240000000663412563340500022510 0ustar carltonstaff00000000000000Metadata-Version: 1.1 Name: django-filter Version: 0.11.0 Summary: Django-filter is a reusable Django application for allowing users to filter querysets dynamically. Home-page: http://github.com/alex/django-filter/tree/master Author: Alex Gaynor Author-email: alex.gaynor@gmail.com License: BSD Description: Django Filter ============= Django-filter is a reusable Django application for allowing users to filter querysets dynamically. Full documentation on `read the docs`_. .. image:: https://secure.travis-ci.org/alex/django-filter.png?branch=master :target: http://travis-ci.org/alex/django-filter Requirements ------------ * Python 2.6+ * Django 1.4.5+ Installation ------------ Install using pip:: pip install django-filter Or clone the repo and add to your PYTHONPATH:: git clone git@github.com:alex/django-filter.git Usage ----- Django-filter can be used for generating interfaces similar to the Django admin's ``list_filter`` interface. It has an API very similar to Django's ``ModelForms``. For example, if you had a Product model you could have a filterset for it with the code:: import django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['name', 'price', 'manufacturer'] And then in your view you could do:: def product_list(request): filter = ProductFilter(request.GET, queryset=Product.objects.all()) return render_to_response('my_app/template.html', {'filter': filter}) Django-filters additionally supports specifying FilterSet fields using a dictionary to specify filters with lookup types:: import django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = {'name': ['exact', 'icontains'], 'price': ['exact', 'gte', 'lte'], } The filters will be available as 'name', 'name__icontains', 'price', 'price__gte', and 'price__lte' in the above example. Support ------- If you have questions about usage or development you can join the `mailing list`_. .. _`read the docs`: https://django-filter.readthedocs.org/en/latest/ .. _`mailing list`: http://groups.google.com/group/django-filter Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Framework :: Django django-filter-0.11.0/django_filter.egg-info/SOURCES.txt0000644000076500000240000000563712563340512023304 0ustar carltonstaff00000000000000AUTHORS CHANGES.rst LICENSE MANIFEST.in README.rst runshell.py runtests.py setup.cfg setup.py django_filter.egg-info/PKG-INFO django_filter.egg-info/SOURCES.txt django_filter.egg-info/dependency_links.txt django_filter.egg-info/not-zip-safe django_filter.egg-info/top_level.txt django_filters/__init__.py django_filters/fields.py django_filters/filters.py django_filters/filterset.py django_filters/models.py django_filters/views.py django_filters/widgets.py django_filters/locale/de/LC_MESSAGES/django.mo django_filters/locale/de/LC_MESSAGES/django.po django_filters/locale/fr/LC_MESSAGES/django.mo django_filters/locale/fr/LC_MESSAGES/django.po docs/.DS_Store docs/Makefile docs/conf.py docs/index.txt docs/install.txt docs/make.bat docs/tests.txt docs/usage.txt docs/_build/.DS_Store docs/_build/doctrees/environment.pickle docs/_build/doctrees/index.doctree docs/_build/doctrees/install.doctree docs/_build/doctrees/tests.doctree docs/_build/doctrees/usage.doctree docs/_build/doctrees/ref/filters.doctree docs/_build/doctrees/ref/widgets.doctree docs/_build/html/.buildinfo docs/_build/html/genindex.html docs/_build/html/index.html docs/_build/html/install.html docs/_build/html/objects.inv docs/_build/html/search.html docs/_build/html/searchindex.js docs/_build/html/tests.html docs/_build/html/usage.html docs/_build/html/_sources/index.txt docs/_build/html/_sources/install.txt docs/_build/html/_sources/tests.txt docs/_build/html/_sources/usage.txt docs/_build/html/_sources/ref/filters.txt docs/_build/html/_sources/ref/widgets.txt docs/_build/html/_static/ajax-loader.gif docs/_build/html/_static/basic.css docs/_build/html/_static/comment-bright.png docs/_build/html/_static/comment-close.png docs/_build/html/_static/comment.png docs/_build/html/_static/default.css docs/_build/html/_static/doctools.js docs/_build/html/_static/down-pressed.png docs/_build/html/_static/down.png docs/_build/html/_static/file.png docs/_build/html/_static/jquery.js docs/_build/html/_static/minus.png docs/_build/html/_static/plus.png docs/_build/html/_static/pygments.css docs/_build/html/_static/searchtools.js docs/_build/html/_static/sidebar.js docs/_build/html/_static/underscore.js docs/_build/html/_static/up-pressed.png docs/_build/html/_static/up.png docs/_build/html/_static/websupport.js docs/_build/html/ref/filters.html docs/_build/html/ref/widgets.html docs/ref/fields.txt docs/ref/filters.txt docs/ref/widgets.txt requirements/docs.txt requirements/maintainer.txt requirements/test.txt requirements/travis-ci.txt tests/__init__.py tests/__init__.pyc tests/models.py tests/models.pyc tests/test_fields.py tests/test_fields.pyc tests/test_filtering.py tests/test_filtering.pyc tests/test_filters.py tests/test_filters.pyc tests/test_filterset.py tests/test_filterset.pyc tests/test_forms.py tests/test_forms.pyc tests/test_views.py tests/test_views.pyc tests/test_widgets.py tests/test_widgets.pyc tests/urls.py tests/urls.pyc tests/templates/tests/book_filter.htmldjango-filter-0.11.0/django_filter.egg-info/top_level.txt0000644000076500000240000000001712563340500024132 0ustar carltonstaff00000000000000django_filters django-filter-0.11.0/django_filters/0000755000076500000240000000000012563340512020076 5ustar carltonstaff00000000000000django-filter-0.11.0/django_filters/__init__.py0000644000076500000240000000074612563340337022223 0ustar carltonstaff00000000000000# flake8: noqa from __future__ import absolute_import from .filterset import FilterSet from .filters import * __version__ = '0.11.0' def parse_version(version): ''' '0.1.2-dev' -> (0, 1, 2, 'dev') '0.1.2' -> (0, 1, 2) ''' v = version.split('.') v = v[:-1] + v[-1].split('-') ret = [] for p in v: if p.isdigit(): ret.append(int(p)) else: ret.append(p) return tuple(ret) VERSION = parse_version(__version__) django-filter-0.11.0/django_filters/fields.py0000644000076500000240000000617212563340337021731 0ustar carltonstaff00000000000000from __future__ import absolute_import from __future__ import unicode_literals from datetime import datetime, time from collections import namedtuple from django import forms from django.utils.dateparse import parse_datetime # TODO: Remove this once Django 1.4 is EOL. try: from django.utils.encoding import force_str except ImportError: force_str = None from .widgets import RangeWidget, LookupTypeWidget class RangeField(forms.MultiValueField): widget = RangeWidget def __init__(self, fields=None, *args, **kwargs): if fields is None: fields = ( forms.DecimalField(), forms.DecimalField()) super(RangeField, self).__init__(fields, *args, **kwargs) def compress(self, data_list): if data_list: return slice(*data_list) return None class DateRangeField(RangeField): def __init__(self, *args, **kwargs): fields = ( forms.DateField(), forms.DateField()) super(DateRangeField, self).__init__(fields, *args, **kwargs) def compress(self, data_list): if data_list: start_date, stop_date = data_list if start_date: start_date = datetime.combine(start_date, time.min) if stop_date: stop_date = datetime.combine(stop_date, time.max) return slice(start_date, stop_date) return None class TimeRangeField(RangeField): def __init__(self, *args, **kwargs): fields = ( forms.TimeField(), forms.TimeField()) super(TimeRangeField, self).__init__(fields, *args, **kwargs) Lookup = namedtuple('Lookup', ('value', 'lookup_type')) class LookupTypeField(forms.MultiValueField): def __init__(self, field, lookup_choices, *args, **kwargs): fields = ( field, forms.ChoiceField(choices=lookup_choices) ) defaults = { 'widgets': [f.widget for f in fields], } widget = LookupTypeWidget(**defaults) kwargs['widget'] = widget super(LookupTypeField, self).__init__(fields, *args, **kwargs) def compress(self, data_list): if len(data_list)==2: return Lookup(value=data_list[0], lookup_type=data_list[1] or 'exact') return Lookup(value=None, lookup_type='exact') class IsoDateTimeField(forms.DateTimeField): """ Supports 'iso-8601' date format too which is out the scope of the ``datetime.strptime`` standard library # ISO 8601: ``http://www.w3.org/TR/NOTE-datetime`` Based on Gist example by David Medina https://gist.github.com/copitux/5773821 """ ISO_8601 = 'iso-8601' input_formats = [ISO_8601] def strptime(self, value, format): # TODO: Remove this once Django 1.4 is EOL. if force_str is not None: value = force_str(value) if format == self.ISO_8601: parsed = parse_datetime(value) if parsed is None: # Continue with other formats if doesn't match raise ValueError return parsed return super(IsoDateTimeField, self).strptime(value, format) django-filter-0.11.0/django_filters/filters.py0000644000076500000240000002555512563340337022141 0ustar carltonstaff00000000000000from __future__ import absolute_import from __future__ import unicode_literals from datetime import timedelta from django import forms from django.db.models import Q from django.db.models.sql.constants import QUERY_TERMS from django.utils import six from django.utils.timezone import now from django.utils.translation import ugettext_lazy as _ from .fields import ( RangeField, LookupTypeField, Lookup, DateRangeField, TimeRangeField, IsoDateTimeField) __all__ = [ 'Filter', 'CharFilter', 'BooleanFilter', 'ChoiceFilter', 'TypedChoiceFilter', 'MultipleChoiceFilter', 'DateFilter', 'DateTimeFilter', 'IsoDateTimeFilter', 'TimeFilter', 'ModelChoiceFilter', 'ModelMultipleChoiceFilter', 'NumberFilter', 'NumericRangeFilter', 'RangeFilter', 'DateRangeFilter', 'DateFromToRangeFilter', 'TimeRangeFilter', 'AllValuesFilter', 'MethodFilter' ] LOOKUP_TYPES = sorted(QUERY_TERMS) class Filter(object): creation_counter = 0 field_class = forms.Field def __init__(self, name=None, label=None, widget=None, action=None, lookup_type='exact', required=False, distinct=False, exclude=False, **kwargs): self.name = name self.label = label if action: self.filter = action self.lookup_type = lookup_type self.widget = widget self.required = required self.extra = kwargs self.distinct = distinct self.exclude = exclude self.creation_counter = Filter.creation_counter Filter.creation_counter += 1 def get_method(self, qs): """Return filter method based on whether we're excluding or simply filtering. """ return qs.exclude if self.exclude else qs.filter @property def field(self): if not hasattr(self, '_field'): help_text = self.extra.pop('help_text', None) if help_text is None: help_text = _('This is an exclusion filter') if self.exclude else _('Filter') if (self.lookup_type is None or isinstance(self.lookup_type, (list, tuple))): if self.lookup_type is None: lookup = [(x, x) for x in LOOKUP_TYPES] else: lookup = [ (x, x) for x in LOOKUP_TYPES if x in self.lookup_type] self._field = LookupTypeField(self.field_class( required=self.required, widget=self.widget, **self.extra), lookup, required=self.required, label=self.label, help_text=help_text) else: self._field = self.field_class(required=self.required, label=self.label, widget=self.widget, help_text=help_text, **self.extra) return self._field def filter(self, qs, value): if isinstance(value, Lookup): lookup = six.text_type(value.lookup_type) value = value.value else: lookup = self.lookup_type if value in ([], (), {}, None, ''): return qs qs = self.get_method(qs)(**{'%s__%s' % (self.name, lookup): value}) if self.distinct: qs = qs.distinct() return qs class CharFilter(Filter): field_class = forms.CharField class BooleanFilter(Filter): field_class = forms.NullBooleanField def filter(self, qs, value): if value is not None: return self.get_method(qs)(**{self.name: value}) return qs class ChoiceFilter(Filter): field_class = forms.ChoiceField class TypedChoiceFilter(Filter): field_class = forms.TypedChoiceField class MultipleChoiceFilter(Filter): """ This filter preforms OR(by default) or AND(using conjoined=True) query on the selected options. Advanced Use ------------ Depending on your application logic, when all or no choices are selected, filtering may be a noop. In this case you may wish to avoid the filtering overhead, particularly if using a `distinct` call. Set `always_filter` to False after instantiation to enable the default `is_noop` test. Override `is_noop` if you require a different test for your application. `distinct` defaults to True on this class to preserve backward compatibility. """ field_class = forms.MultipleChoiceField always_filter = True def __init__(self, *args, **kwargs): distinct = kwargs.get('distinct', True) kwargs['distinct'] = distinct conjoined = kwargs.pop('conjoined', False) self.conjoined = conjoined super(MultipleChoiceFilter, self).__init__(*args, **kwargs) def is_noop(self, qs, value): """ Return True to short-circuit unnecessary and potentially slow filtering. """ if self.always_filter: return False # A reasonable default for being a noop... if self.required and len(value) == len(self.field.choices): return True return False def filter(self, qs, value): value = value or () # Make sure we have an iterable if self.is_noop(qs, value): return qs # Even though not a noop, no point filtering if empty if not value: return qs q = Q() for v in set(value): if self.conjoined: qs = self.get_method(qs)(**{self.name: v}) else: q |= Q(**{self.name: v}) if self.distinct: return self.get_method(qs)(q).distinct() return self.get_method(qs)(q) class DateFilter(Filter): field_class = forms.DateField class DateTimeFilter(Filter): field_class = forms.DateTimeField class IsoDateTimeFilter(DateTimeFilter): """ Uses IsoDateTimeField to support filtering on ISO 8601 formated datetimes. For context see: * https://code.djangoproject.com/ticket/23448 * https://github.com/tomchristie/django-rest-framework/issues/1338 * https://github.com/alex/django-filter/pull/264 """ field_class = IsoDateTimeField class TimeFilter(Filter): field_class = forms.TimeField class ModelChoiceFilter(Filter): field_class = forms.ModelChoiceField class ModelMultipleChoiceFilter(MultipleChoiceFilter): field_class = forms.ModelMultipleChoiceField class NumberFilter(Filter): field_class = forms.DecimalField class NumericRangeFilter(Filter): field_class = RangeField def filter(self, qs, value): if value: if value.start is not None and value.stop is not None: lookup = '%s__%s' % (self.name, self.lookup_type) return self.get_method(qs)(**{lookup: (value.start, value.stop)}) else: if value.start is not None: qs = self.get_method(qs)(**{'%s__startswith' % self.name: value.start}) if value.stop is not None: qs = self.get_method(qs)(**{'%s__endswith' % self.name: value.stop}) return qs class RangeFilter(Filter): field_class = RangeField def filter(self, qs, value): if value: if value.start is not None and value.stop is not None: lookup = '%s__range' % self.name return self.get_method(qs)(**{lookup: (value.start, value.stop)}) else: if value.start is not None: qs = self.get_method(qs)(**{'%s__gte'%self.name:value.start}) if value.stop is not None: qs = self.get_method(qs)(**{'%s__lte'%self.name:value.stop}) return qs _truncate = lambda dt: dt.replace(hour=0, minute=0, second=0) class DateRangeFilter(ChoiceFilter): options = { '': (_('Any date'), lambda qs, name: qs.all()), 1: (_('Today'), lambda qs, name: qs.filter(**{ '%s__year' % name: now().year, '%s__month' % name: now().month, '%s__day' % name: now().day })), 2: (_('Past 7 days'), lambda qs, name: qs.filter(**{ '%s__gte' % name: _truncate(now() - timedelta(days=7)), '%s__lt' % name: _truncate(now() + timedelta(days=1)), })), 3: (_('This month'), lambda qs, name: qs.filter(**{ '%s__year' % name: now().year, '%s__month' % name: now().month })), 4: (_('This year'), lambda qs, name: qs.filter(**{ '%s__year' % name: now().year, })), 5: (_('Yesterday'), lambda qs, name: qs.filter(**{ '%s__year' % name: now().year, '%s__month' % name: now().month, '%s__day' % name: (now() - timedelta(days=1)).day, })), } def __init__(self, *args, **kwargs): kwargs['choices'] = [ (key, value[0]) for key, value in six.iteritems(self.options)] super(DateRangeFilter, self).__init__(*args, **kwargs) def filter(self, qs, value): try: value = int(value) except (ValueError, TypeError): value = '' return self.options[value][1](qs, self.name) class DateFromToRangeFilter(RangeFilter): field_class = DateRangeField class TimeRangeFilter(RangeFilter): field_class = TimeRangeField class AllValuesFilter(ChoiceFilter): @property def field(self): qs = self.model._default_manager.distinct() qs = qs.order_by(self.name).values_list(self.name, flat=True) self.extra['choices'] = [(o, o) for o in qs] return super(AllValuesFilter, self).field class MethodFilter(Filter): """ This filter will allow you to run a method that exists on the filterset class """ def __init__(self, *args, **kwargs): # Get the action out of the kwargs action = kwargs.get('action', None) # If the action is a string store the action and set the action to our own filter method # so it can be backwards compatible and work as expected, the parent will still treat it as # a filter that has an action self.parent_action = '' text_types = (str, six.text_type) if type(action) in text_types: self.parent_action = str(action) kwargs.update({ 'action': self.filter }) # Call the parent super(MethodFilter, self).__init__(*args, **kwargs) def filter(self, qs, value): """ This filter method will act as a proxy for the actual method we want to call. It will try to find the method on the parent filterset, if not it attempts to search for the method `field_{{attribute_name}}`. Otherwise it defaults to just returning the queryset. """ parent = getattr(self, 'parent', None) parent_filter_method = getattr(parent, self.parent_action, None) if not parent_filter_method: func_str = 'filter_{0}'.format(self.name) parent_filter_method = getattr(parent, func_str, None) if parent_filter_method is not None: return parent_filter_method(qs, value) return qs django-filter-0.11.0/django_filters/filterset.py0000644000076500000240000004122412563340337022461 0ustar carltonstaff00000000000000from __future__ import absolute_import from __future__ import unicode_literals import types import copy from django import forms from django.forms.forms import NON_FIELD_ERRORS from django.core.validators import EMPTY_VALUES from django.db import models from django.db.models.fields import FieldDoesNotExist from django.utils import six from django.utils.text import capfirst from django.utils.translation import ugettext as _ from sys import version_info try: from django.db.models.constants import LOOKUP_SEP except ImportError: # pragma: nocover # Django < 1.5 fallback from django.db.models.sql.constants import LOOKUP_SEP # noqa try: from collections import OrderedDict except ImportError: # pragma: nocover # 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, ModelMultipleChoiceFilter, NumberFilter) ORDER_BY_FIELD = 'o' # There is a bug with deepcopy in 2.6, patch if we are running python < 2.7 # http://bugs.python.org/issue1515 if version_info < (2, 7, 0): def _deepcopy_method(x, memo): return type(x)(x.im_func, copy.deepcopy(x.im_self, memo), x.im_class) copy._deepcopy_dispatch[types.MethodType] = _deepcopy_method class STRICTNESS(object): """ Values of False & True chosen for backward compatability reasons. Originally, these were the only options. """ IGNORE = False RETURN_NO_RESULTS = True RAISE_VALIDATION_ERROR = "RAISE" def get_declared_filters(bases, attrs, with_base_filters=True): filters = [] for filter_name, obj in list(attrs.items()): if isinstance(obj, Filter): obj = attrs.pop(filter_name) if getattr(obj, 'name', None) is None: obj.name = filter_name filters.append((filter_name, obj)) filters.sort(key=lambda x: x[1].creation_counter) if with_base_filters: for base in bases[::-1]: if hasattr(base, 'base_filters'): filters = list(base.base_filters.items()) + filters else: for base in bases[::-1]: if hasattr(base, 'declared_filters'): filters = list(base.declared_filters.items()) + filters return OrderedDict(filters) def get_model_field(model, f): parts = f.split(LOOKUP_SEP) opts = model._meta for name in parts[:-1]: try: rel = opts.get_field_by_name(name)[0] except FieldDoesNotExist: return None if isinstance(rel, ForeignObjectRel): if hasattr(rel, "related_model"): # django >= 1.8 (ForeignObjectRel) opts = rel.related_model._meta else: # django < 1.8 (RelatedObject) opts = rel.opts else: model = rel.rel.to opts = model._meta try: rel, model, direct, m2m = opts.get_field_by_name(parts[-1]) except FieldDoesNotExist: return None return rel def filters_for_model(model, fields=None, exclude=None, filter_for_field=None, filter_for_reverse_field=None): field_dict = OrderedDict() opts = model._meta if fields is None: fields = [f.name for f in sorted(opts.fields + opts.many_to_many) if not isinstance(f, models.AutoField)] # Loop through the list of fields. for f in fields: # Skip the field if excluded. if exclude is not None and f in exclude: continue field = get_model_field(model, f) # Do nothing if the field doesn't exist. if field is None: field_dict[f] = None continue if isinstance(field, ForeignObjectRel): filter_ = filter_for_reverse_field(field, f) if filter_: field_dict[f] = filter_ # If fields is a dictionary, it must contain lists. elif isinstance(fields, dict): # Create a filter for each lookup type. for lookup_type in fields[f]: filter_ = filter_for_field(field, f, lookup_type) if filter_: filter_name = f # Don't add "exact" to filter names if lookup_type != 'exact': filter_name = f + LOOKUP_SEP + lookup_type field_dict[filter_name] = filter_ # If fields is a list, it contains strings. else: filter_ = filter_for_field(field, f) if filter_: field_dict[f] = filter_ return field_dict def get_full_clean_override(together): def full_clean(form): def add_error(message): try: form.add_error(None, message) except AttributeError: form._errors[NON_FIELD_ERRORS] = message def all_valid(fieldset): cleaned_data = form.cleaned_data count = len([i for i in fieldset if cleaned_data.get(i)]) return 0 < count < len(fieldset) super(form.__class__, form).full_clean() message = 'Following fields must be together: %s' if isinstance(together[0], (list, tuple)): for each in together: if all_valid(each): return add_error(message % ','.join(each)) elif all_valid(together): return add_error(message % ','.join(together)) return full_clean class FilterSetOptions(object): def __init__(self, options=None): self.model = getattr(options, 'model', None) self.fields = getattr(options, 'fields', None) self.exclude = getattr(options, 'exclude', None) self.order_by = getattr(options, 'order_by', False) self.form = getattr(options, 'form', forms.Form) self.together = getattr(options, 'together', None) class FilterSetMetaclass(type): def __new__(cls, name, bases, attrs): try: parents = [b for b in bases if issubclass(b, FilterSet)] except NameError: # We are defining FilterSet itself here parents = None declared_filters = get_declared_filters(bases, attrs, False) new_class = super( FilterSetMetaclass, cls).__new__(cls, name, bases, attrs) if not parents: return new_class opts = new_class._meta = FilterSetOptions( getattr(new_class, 'Meta', None)) if opts.model: filters = filters_for_model(opts.model, opts.fields, opts.exclude, new_class.filter_for_field, new_class.filter_for_reverse_field) filters.update(declared_filters) else: filters = declared_filters if None in filters.values(): raise TypeError("Meta.fields contains a field that isn't defined " "on this FilterSet") new_class.declared_filters = declared_filters new_class.base_filters = filters return new_class FILTER_FOR_DBFIELD_DEFAULTS = { models.AutoField: { 'filter_class': NumberFilter }, models.CharField: { 'filter_class': CharFilter }, models.TextField: { 'filter_class': CharFilter }, models.BooleanField: { 'filter_class': BooleanFilter }, models.DateField: { 'filter_class': DateFilter }, models.DateTimeField: { 'filter_class': DateTimeFilter }, models.TimeField: { 'filter_class': TimeFilter }, models.OneToOneField: { 'filter_class': ModelChoiceFilter, 'extra': lambda f: { 'queryset': f.rel.to._default_manager.complex_filter( f.rel.limit_choices_to), 'to_field_name': f.rel.field_name, } }, models.ForeignKey: { 'filter_class': ModelChoiceFilter, 'extra': lambda f: { 'queryset': f.rel.to._default_manager.complex_filter( f.rel.limit_choices_to), 'to_field_name': f.rel.field_name } }, models.ManyToManyField: { 'filter_class': ModelMultipleChoiceFilter, 'extra': lambda f: { 'queryset': f.rel.to._default_manager.complex_filter( f.rel.limit_choices_to), } }, models.DecimalField: { 'filter_class': NumberFilter, }, models.SmallIntegerField: { 'filter_class': NumberFilter, }, models.IntegerField: { 'filter_class': NumberFilter, }, models.PositiveIntegerField: { 'filter_class': NumberFilter, }, models.PositiveSmallIntegerField: { 'filter_class': NumberFilter, }, models.FloatField: { 'filter_class': NumberFilter, }, models.NullBooleanField: { 'filter_class': BooleanFilter, }, models.SlugField: { 'filter_class': CharFilter, }, models.EmailField: { 'filter_class': CharFilter, }, models.FilePathField: { 'filter_class': CharFilter, }, models.URLField: { 'filter_class': CharFilter, }, models.IPAddressField: { 'filter_class': CharFilter, }, models.CommaSeparatedIntegerField: { 'filter_class': CharFilter, }, } class BaseFilterSet(object): filter_overrides = {} order_by_field = ORDER_BY_FIELD # What to do on on validation errors strict = STRICTNESS.RETURN_NO_RESULTS def __init__(self, data=None, queryset=None, prefix=None, strict=None): self.is_bound = data is not None self.data = data or {} if queryset is None: queryset = self._meta.model._default_manager.all() self.queryset = queryset self.form_prefix = prefix if strict is not None: self.strict = strict self.filters = copy.deepcopy(self.base_filters) # propagate the model being used through the filters for filter_ in self.filters.values(): filter_.model = self._meta.model # Apply the parent to the filters, this will allow the filters to access the filterset for filter_key, filter_ in six.iteritems(self.filters): filter_.parent = self def __iter__(self): for obj in self.qs: yield obj def __len__(self): return len(self.qs) def __getitem__(self, key): return self.qs[key] @property def qs(self): if not hasattr(self, '_qs'): valid = self.is_bound and self.form.is_valid() if self.is_bound and not valid: if self.strict == STRICTNESS.RAISE_VALIDATION_ERROR: raise forms.ValidationError(self.form.errors) elif bool(self.strict) == STRICTNESS.RETURN_NO_RESULTS: self._qs = self.queryset.none() return self._qs # else STRICTNESS.IGNORE... ignoring # start with all the results and filter from there qs = self.queryset.all() for name, filter_ in six.iteritems(self.filters): value = None if valid: value = self.form.cleaned_data[name] else: raw_value = self.form[name].value() try: value = self.form.fields[name].clean(raw_value) except forms.ValidationError: if self.strict == STRICTNESS.RAISE_VALIDATION_ERROR: raise elif bool(self.strict) == STRICTNESS.RETURN_NO_RESULTS: self._qs = self.queryset.none() return self._qs # else STRICTNESS.IGNORE... ignoring if value is not None: # valid & clean data qs = filter_.filter(qs, value) if self._meta.order_by: order_field = self.form.fields[self.order_by_field] data = self.form[self.order_by_field].data ordered_value = None try: ordered_value = order_field.clean(data) except forms.ValidationError: pass if ordered_value in EMPTY_VALUES and self.strict: ordered_value = self.form.fields[self.order_by_field].choices[0][0] if ordered_value: qs = qs.order_by(*self.get_order_by(ordered_value)) self._qs = qs return self._qs def count(self): return self.qs.count() @property def form(self): if not hasattr(self, '_form'): fields = OrderedDict([ (name, filter_.field) for name, filter_ in six.iteritems(self.filters)]) fields[self.order_by_field] = self.ordering_field Form = type(str('%sForm' % self.__class__.__name__), (self._meta.form,), fields) if self._meta.together: Form.full_clean = get_full_clean_override(self._meta.together) if self.is_bound: self._form = Form(self.data, prefix=self.form_prefix) else: self._form = Form(prefix=self.form_prefix) return self._form def get_ordering_field(self): if self._meta.order_by: if isinstance(self._meta.order_by, (list, tuple)): if isinstance(self._meta.order_by[0], (list, tuple)): # e.g. (('field', 'Display name'), ...) choices = [(f[0], f[1]) for f in self._meta.order_by] else: choices = [(f, _('%s (descending)' % capfirst(f[1:])) if f[0] == '-' else capfirst(f)) for f in self._meta.order_by] else: # add asc and desc field names # use the filter's label if provided choices = [] for f, fltr in self.filters.items(): choices.extend([ (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, choices=choices) @property def ordering_field(self): if not hasattr(self, '_ordering_field'): self._ordering_field = self.get_ordering_field() return self._ordering_field def get_order_by(self, order_choice): return [order_choice] @classmethod def filter_for_field(cls, f, name, lookup_type='exact'): filter_for_field = dict(FILTER_FOR_DBFIELD_DEFAULTS) filter_for_field.update(cls.filter_overrides) default = { 'name': name, 'label': capfirst(f.verbose_name), 'lookup_type': lookup_type } if f.choices: default['choices'] = f.choices return ChoiceFilter(**default) data = filter_for_field.get(f.__class__) if data is None: # could be a derived field, inspect parents for class_ in f.__class__.mro(): # skip if class_ is models.Field or object # 1st item in mro() is original class if class_ in (f.__class__, models.Field, object): continue data = filter_for_field.get(class_) if data: break if data is None: return filter_class = data.get('filter_class') default.update(data.get('extra', lambda f: {})(f)) if filter_class is not None: return filter_class(**default) @classmethod def filter_for_reverse_field(cls, f, name): rel = f.field.rel queryset = f.field.model._default_manager.all() default = { 'name': name, 'label': capfirst(rel.related_name), 'queryset': queryset, } if rel.multiple: return ModelMultipleChoiceFilter(**default) else: return ModelChoiceFilter(**default) class FilterSet(six.with_metaclass(FilterSetMetaclass, BaseFilterSet)): pass def filterset_factory(model): meta = type(str('Meta'), (object,), {'model': model}) filterset = type(str('%sFilterSet' % model._meta.object_name), (FilterSet,), {'Meta': meta}) return filterset django-filter-0.11.0/django_filters/locale/0000755000076500000240000000000012563340512021335 5ustar carltonstaff00000000000000django-filter-0.11.0/django_filters/locale/de/0000755000076500000240000000000012563340512021725 5ustar carltonstaff00000000000000django-filter-0.11.0/django_filters/locale/de/LC_MESSAGES/0000755000076500000240000000000012563340512023512 5ustar carltonstaff00000000000000django-filter-0.11.0/django_filters/locale/de/LC_MESSAGES/django.mo0000644000076500000240000000133312410601557025311 0ustar carltonstaff00000000000000Þ•\ œÈÉÙÝ æ ò ý€ Žž £ ® ¼ ÉÕ%s (descending)AllAny datePast 7 daysThis monthThis yearTodayProject-Id-Version: django-filter Report-Msgid-Bugs-To: POT-Creation-Date: 2013-08-10 05:34-0500 PO-Revision-Date: 2013-08-10 12:29+0100 Last-Translator: Florian Apolloner Language-Team: Language: de MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Generator: Poedit 1.5.4 %s (absteigend)AlleAlle DatenLetzte 7 TageDiesen MonatDieses JahrHeutedjango-filter-0.11.0/django_filters/locale/de/LC_MESSAGES/django.po0000644000076500000240000000206312410601557025315 0ustar carltonstaff00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: django-filter\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-10 05:34-0500\n" "PO-Revision-Date: 2013-08-10 12:29+0100\n" "Last-Translator: Florian Apolloner \n" "Language-Team: \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 1.5.4\n" #: filters.py:153 msgid "Any date" msgstr "Alle Daten" #: filters.py:154 msgid "Today" msgstr "Heute" #: filters.py:159 msgid "Past 7 days" msgstr "Letzte 7 Tage" #: filters.py:163 msgid "This month" msgstr "Diesen Monat" #: filters.py:167 msgid "This year" msgstr "Dieses Jahr" #: filterset.py:332 filterset.py:341 #, python-format msgid "%s (descending)" msgstr "%s (absteigend)" #: widgets.py:63 msgid "All" msgstr "Alle" django-filter-0.11.0/django_filters/locale/fr/0000755000076500000240000000000012563340512021744 5ustar carltonstaff00000000000000django-filter-0.11.0/django_filters/locale/fr/LC_MESSAGES/0000755000076500000240000000000012563340512023531 5ustar carltonstaff00000000000000django-filter-0.11.0/django_filters/locale/fr/LC_MESSAGES/django.mo0000644000076500000240000000140012411012542025312 0ustar carltonstaff00000000000000Þ•\ œÈÉÍ Öâ þ |–›¬½ Ü ç ôAllAny datePast 7 daysThis is an exclusion filterThis monthThis yearTodayProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2013-07-05 19:24+0200 PO-Revision-Date: 2013-07-05 19:24+0200 Last-Translator: Axel Haustant Language-Team: LANGUAGE Language: French MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n > 1); TousToutes les dates7 derniers joursCeci est un filtre d'exclusionCe mois-ciCette annéeAujourd'huidjango-filter-0.11.0/django_filters/locale/fr/LC_MESSAGES/django.po0000644000076500000240000000205312411012542025322 0ustar carltonstaff00000000000000# Django Filter translation. # Copyright (C) 2013 # This file is distributed under the same license as the django_filter package. # Axel Haustant , 2013. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-07-05 19:24+0200\n" "PO-Revision-Date: 2013-07-05 19:24+0200\n" "Last-Translator: Axel Haustant \n" "Language-Team: LANGUAGE \n" "Language: French\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #: filters.py:51 msgid "This is an exclusion filter" msgstr "Ceci est un filtre d'exclusion" #: filters.py:158 msgid "Any date" msgstr "Toutes les dates" #: filters.py:159 msgid "Today" msgstr "Aujourd'hui" #: filters.py:164 msgid "Past 7 days" msgstr "7 derniers jours" #: filters.py:168 msgid "This month" msgstr "Ce mois-ci" #: filters.py:172 msgid "This year" msgstr "Cette année" #: widgets.py:63 msgid "All" msgstr "Tous" django-filter-0.11.0/django_filters/models.py0000644000076500000240000000000012410601557021721 0ustar carltonstaff00000000000000django-filter-0.11.0/django_filters/views.py0000644000076500000240000000706012410601557021610 0ustar carltonstaff00000000000000from __future__ import absolute_import from __future__ import unicode_literals from django.core.exceptions import ImproperlyConfigured from django.views.generic import View from django.views.generic.list import MultipleObjectMixin from django.views.generic.list import MultipleObjectTemplateResponseMixin from .filterset import filterset_factory class FilterMixin(object): """ A mixin that provides a way to show and handle a FilterSet in a request. """ filterset_class = None def get_filterset_class(self): """ Returns the filterset class to use in this view """ if self.filterset_class: return self.filterset_class elif self.model: return filterset_factory(self.model) else: msg = "'%s' must define 'filterset_class' or 'model'" raise ImproperlyConfigured(msg % self.__class__.__name__) def get_filterset(self, filterset_class): """ Returns an instance of the filterset to be used in this view. """ kwargs = self.get_filterset_kwargs(filterset_class) return filterset_class(**kwargs) def get_filterset_kwargs(self, filterset_class): """ Returns the keyword arguments for instanciating the filterset. """ kwargs = {'data': self.request.GET or None} try: kwargs.update({ 'queryset': self.get_queryset(), }) except ImproperlyConfigured: # ignore the error here if the filterset has a model defined # to acquire a queryset from if filterset_class._meta.model is None: 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.") args = (filterset_class.__name__, self.__class__.__name__) raise ImproperlyConfigured(msg % args) return kwargs class BaseFilterView(FilterMixin, MultipleObjectMixin, View): def get(self, request, *args, **kwargs): filterset_class = self.get_filterset_class() self.filterset = self.get_filterset(filterset_class) self.object_list = self.filterset.qs context = self.get_context_data(filter=self.filterset, object_list=self.object_list) return self.render_to_response(context) class FilterView(MultipleObjectTemplateResponseMixin, BaseFilterView): """ Render some list of objects with filter, set by `self.model` or `self.queryset`. `self.queryset` can actually be any iterable of items, not just a queryset. """ template_name_suffix = '_filter' def object_filter(request, model=None, queryset=None, template_name=None, extra_context=None, context_processors=None, filter_class=None): class ECFilterView(FilterView): """Handle the extra_context from the functional object_filter view""" def get_context_data(self, **kwargs): context = super(ECFilterView, self).get_context_data(**kwargs) extra_context = self.kwargs.get('extra_context') or {} for k, v in extra_context.items(): if callable(v): v = v() context[k] = v return context kwargs = dict(model=model, queryset=queryset, template_name=template_name, filterset_class=filter_class) view = ECFilterView.as_view(**kwargs) return view(request, extra_context=extra_context) django-filter-0.11.0/django_filters/widgets.py0000644000076500000240000000652112410601557022122 0ustar carltonstaff00000000000000from __future__ import absolute_import from __future__ import unicode_literals from itertools import chain try: from urllib.parse import urlencode except: from urllib import urlencode # noqa from django import forms from django.db.models.fields import BLANK_CHOICE_DASH from django.forms.widgets import flatatt try: from django.utils.encoding import force_text 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 _ class LinkWidget(forms.Widget): def __init__(self, attrs=None, choices=()): super(LinkWidget, self).__init__(attrs) self.choices = choices def value_from_datadict(self, data, files, name): value = super(LinkWidget, self).value_from_datadict(data, files, name) self.data = data return value def render(self, name, value, attrs=None, choices=()): if not hasattr(self, 'data'): self.data = {} if value is None: value = '' final_attrs = self.build_attrs(attrs) output = ['' % flatatt(final_attrs)] options = self.render_options(choices, [value], name) if options: output.append(options) output.append('') return mark_safe('\n'.join(output)) def render_options(self, choices, selected_choices, name): selected_choices = set(force_text(v) for v in selected_choices) output = [] for option_value, option_label in chain(self.choices, choices): if isinstance(option_label, (list, tuple)): for option in option_label: output.append( self.render_option(name, selected_choices, *option)) else: output.append( self.render_option(name, selected_choices, option_value, option_label)) return '\n'.join(output) def render_option(self, name, selected_choices, option_value, option_label): option_value = force_text(option_value) if option_label == BLANK_CHOICE_DASH[0][1]: option_label = _("All") data = self.data.copy() data[name] = option_value selected = data == self.data or option_value in selected_choices try: url = data.urlencode() except AttributeError: url = urlencode(data) return self.option_string() % { 'attrs': selected and ' class="selected"' or '', 'query_string': url, 'label': force_text(option_label) } def option_string(self): return '
  • %(label)s
  • ' class RangeWidget(forms.MultiWidget): def __init__(self, attrs=None): widgets = (forms.TextInput(attrs=attrs), forms.TextInput(attrs=attrs)) super(RangeWidget, self).__init__(widgets, attrs) def decompress(self, value): if value: return [value.start, value.stop] return [None, None] def format_output(self, rendered_widgets): return '-'.join(rendered_widgets) class LookupTypeWidget(forms.MultiWidget): def decompress(self, value): if value is None: return [None, None] return value django-filter-0.11.0/docs/0000755000076500000240000000000012563340512016034 5ustar carltonstaff00000000000000django-filter-0.11.0/docs/.DS_Store0000644000076500000240000001400412435162061017515 0ustar carltonstaff00000000000000Bud1†ldvSrnlong_buildvSrnlong  @€ @€ @€ @ E†DSDB `À @€ @€ @django-filter-0.11.0/docs/_build/0000755000076500000240000000000012563340512017272 5ustar carltonstaff00000000000000django-filter-0.11.0/docs/_build/.DS_Store0000644000076500000240000001400412436125062020754 0ustar carltonstaff00000000000000Bud1 bwspblobùhtmlbwspblobùbplist00Ù  ]ShowStatusBar[ShowSidebar[ShowPathbar[ShowToolbar[ShowTabView_ContainerShowSidebar\WindowBounds\SidebarWidth_PreviewPaneVisibility  _{{461, 200}, {770, 449}}†)5AMYp}Š¢£¤¥¦§¨ÃÅÆhtmlvSrnlong  @€ @€ @€ @ E DSDB `€ @€ @€ @django-filter-0.11.0/docs/_build/doctrees/0000755000076500000240000000000012563340512021102 5ustar carltonstaff00000000000000django-filter-0.11.0/docs/_build/doctrees/environment.pickle0000644000076500000240000005450112436054334024647 0ustar carltonstaff00000000000000€(csphinx.environment BuildEnvironment qoq}q(Udlfilesqcsphinx.util FilenameUniqDict q)qc__builtin__ set q]…RqbUappq NU reread_alwaysq h]…Rq Utitlesq }q (Xindexqcdocutils.nodes title q)q}q(U rawsourceqUU attributesq}q(Udupnamesq]Uclassesq]Ubackrefsq]Uidsq]Unamesq]uUchildrenq]qcdocutils.nodes Text qX django-filterq…q}q(hX django-filterq Uparentq!hubaUtagnameq"Utitleq#ubXtestsq$h)q%}q&(hUh}q'(h]h]h]h]h]uh]q(hXRunning the django-filter testsq)…q*}q+(hXRunning the django-filter testsq,h!h%ubah"h#ubXusageq-h)q.}q/(hUh}q0(h]h]h]h]h]uh]q1hXUsing django-filterq2…q3}q4(hXUsing django-filterq5h!h.ubah"h#ubX ref/widgetsq6h)q7}q8(hUh}q9(h]h]h]h]h]uh]q:hXWidget Referenceq;…q<}q=(hXWidget Referenceq>h!h7ubah"h#ubXinstallq?h)q@}qA(hUh}qB(h]h]h]h]h]uh]qChXInstalling django-filterqD…qE}qF(hXInstalling django-filterqGh!h@ubah"h#ubX ref/filtersqHh)qI}qJ(hUh}qK(h]h]h]h]h]uh]qLhXFilter ReferenceqM…qN}qO(hXFilter ReferenceqPh!hIubah"h#ubuU domaindataqQ}qR(Ustd}qS(U anonlabels}qT(UmodindexqUU py-modindexU†UgenindexqVhVU†UsearchqWUsearchU†uUlabels}qX(hUU py-modindexUcsphinx.locale _TranslationProxy qYcsphinx.locale mygettext qZU Module Indexq[†q\hZh[…q]†b‡hVhVUhYhZUIndexq^†q_hZh^…q`†b‡hWhWUhYhZU Search Pageqa†qbhZha…qc†b‡uUversionqdKUobjectsqe}U progoptions}uUc}qf(he}hdKuUpy}qg(he}Umodules}hdKuUjs}qh(he}hdKuUrst}qi(he}hdKuUcpp}qj(he}hdKuuU glob_toctreesqkh]…RqlUimagesqmh)qnh]…RqobU doctreedirqpXH/Users/carlton/Documents/Django-Stack/django-filter/docs/_build/doctreesqqUversioning_conditionqr‰U citationsqs}UversionqtK*UsrcdirquX8/Users/carlton/Documents/Django-Stack/django-filter/docsqvUconfigqwcsphinx.config Config qx)qy}qz(U source_suffixq{U.txtU copyrightq|X2013, Alex Gaynor and others.Ulatex_elementsq}}Utemplates_pathq~]qU _templatesq€aUexclude_patternsq]q‚U_buildqƒaU overridesq„}Upygments_styleq…Usphinxq†Ulatex_documentsq‡]qˆ(Uasdq‰Udjango-filter.texXdjango-filter DocumentationqŠXAlex Gaynor and others.q‹UmanualtqŒaUreleaseqU0.9.0qŽUprojectqX django-filterUtexinfo_documentsq]q‘(h‰U django-filterq’hŠh‹h’U One line description of project.U Miscellaneoustq“aUhtmlhelp_basenameq”Udjango-filterdochthŽU extensionsq•]U html_themeq–Udefaultq—U man_pagesq˜]q™(h‰h’hŠ]qšh‹aKtq›aU master_docqœUindexqUsetupqžNubUmetadataqŸ}q (h}h$}h-}h6}h?}hH}uUversionchangesq¡}Utoc_num_entriesq¢}q£(hKh$Kh-Kh6Kh?KhHKuUnumbered_toctreesq¤h]…Rq¥U found_docsq¦h]q§(hh$hHh6h?h-e…Rq¨U longtitlesq©}qª(hhh$h%h-h.h6h7h?h@hHhIuU dependenciesq«}Utoctree_includesq¬}q­h]q®(Xinstallq¯Xusageq°X ref/filtersq±X ref/widgetsq²Xtestsq³esU temp_dataq´}Utocsqµ}q¶(hcdocutils.nodes bullet_list q·)q¸}q¹(hUh}qº(h]h]h]h]h]uh]q»cdocutils.nodes list_item q¼)q½}q¾(hUh}q¿(h]h]h]h]h]uh!h¸h]qÀ(csphinx.addnodes compact_paragraph qÁ)qÂ}qÃ(hUh}qÄ(h]h]h]h]h]uh!h½h]qÅcdocutils.nodes reference qÆ)qÇ}qÈ(hUh}qÉ(U anchornameUUrefurihh]h]h]h]h]Uinternalˆuh!hÂh]qÊhX django-filterqË…qÌ}qÍ(hh h!hÇubah"U referenceqÎubah"Ucompact_paragraphqÏubh·)qÐ}qÑ(hUh}qÒ(h]h]h]h]h]uh!h½h]qÓcsphinx.addnodes toctree qÔ)qÕ}qÖ(hUh}q×(UnumberedKUparenthU titlesonly‰Uglob‰h]h]h]h]h]Uentries]qØ(Nh¯†qÙNh°†qÚNh±†qÛNh²†qÜNh³†qÝeUhidden‰UmaxdepthKU includefiles]qÞ(h¯h°h±h²h³eU includehidden‰uh!hÐh]h"Utoctreeqßubah"U bullet_listqàubeh"U list_itemqáubah"hàubh$h·)qâ}qã(hUh}qä(h]h]h]h]h]uh]qåh¼)qæ}qç(hUh}qè(h]h]h]h]h]uh!hâh]qé(hÁ)qê}që(hUh}qì(h]h]h]h]h]uh!hæh]qíhÆ)qî}qï(hUh}qð(U anchornameUUrefurih$h]h]h]h]h]Uinternalˆuh!hêh]qñhXRunning the django-filter testsqò…qó}qô(hh,h!hîubah"hÎubah"hÏubh·)qõ}qö(hUh}q÷(h]h]h]h]h]uh!hæh]qø(h¼)qù}qú(hUh}qû(h]h]h]h]h]uh!hõh]qühÁ)qý}qþ(hUh}qÿ(h]h]h]h]h]uh!hùh]rhÆ)r}r(hUh}r(U anchornameU'#set-up-a-virtualenv-for-the-test-suiteUrefurih$h]h]h]h]h]Uinternalˆuh!hýh]rhX&Set up a virtualenv for the test suiter…r}r(hX&Set up a virtualenv for the test suiteh!jubah"hÎubah"hÏubah"háubh¼)r}r (hUh}r (h]h]h]h]h]uh!hõh]r hÁ)r }r (hUh}r(h]h]h]h]h]uh!jh]rhÆ)r}r(hUh}r(U anchornameU#get-a-copy-of-django-filterUrefurih$h]h]h]h]h]Uinternalˆuh!j h]rhXGet a copy of django-filterr…r}r(hXGet a copy of django-filterh!jubah"hÎubah"hÏubah"háubh¼)r}r(hUh}r(h]h]h]h]h]uh!hõh]rhÁ)r}r(hUh}r(h]h]h]h]h]uh!jh]rhÆ)r}r (hUh}r!(U anchornameU#install-the-test-dependenciesUrefurih$h]h]h]h]h]Uinternalˆuh!jh]r"hXInstall the test dependenciesr#…r$}r%(hXInstall the test dependenciesh!jubah"hÎubah"hÏubah"háubeh"hàubeh"háubah"hàubh-h·)r&}r'(hUh}r((h]h]h]h]h]uh]r)h¼)r*}r+(hUh}r,(h]h]h]h]h]uh!j&h]r-(hÁ)r.}r/(hUh}r0(h]h]h]h]h]uh!j*h]r1hÆ)r2}r3(hUh}r4(U anchornameUUrefurih-h]h]h]h]h]Uinternalˆuh!j.h]r5hXUsing django-filterr6…r7}r8(hh5h!j2ubah"hÎubah"hÏubh·)r9}r:(hUh}r;(h]h]h]h]h]uh!j*h]r<(h¼)r=}r>(hUh}r?(h]h]h]h]h]uh!j9h]r@hÁ)rA}rB(hUh}rC(h]h]h]h]h]uh!j=h]rDhÆ)rE}rF(hUh}rG(U anchornameU #the-modelUrefurih-h]h]h]h]h]Uinternalˆuh!jAh]rHhX The modelrI…rJ}rK(hX The modelrLh!jEubah"hÎubah"hÏubah"háubh¼)rM}rN(hUh}rO(h]h]h]h]h]uh!j9h]rPhÁ)rQ}rR(hUh}rS(h]h]h]h]h]uh!jMh]rThÆ)rU}rV(hUh}rW(U anchornameU #the-filterUrefurih-h]h]h]h]h]Uinternalˆuh!jQh]rXhX The filterrY…rZ}r[(hX The filterr\h!jUubah"hÎubah"hÏubah"háubh¼)r]}r^(hUh}r_(h]h]h]h]h]uh!j9h]r`hÁ)ra}rb(hUh}rc(h]h]h]h]h]uh!j]h]rdhÆ)re}rf(hUh}rg(U anchornameU #the-viewUrefurih-h]h]h]h]h]Uinternalˆuh!jah]rhhXThe viewri…rj}rk(hXThe viewrlh!jeubah"hÎubah"hÏubah"háubh¼)rm}rn(hUh}ro(h]h]h]h]h]uh!j9h]rphÁ)rq}rr(hUh}rs(h]h]h]h]h]uh!jmh]rthÆ)ru}rv(hUh}rw(U anchornameU #the-url-confUrefurih-h]h]h]h]h]Uinternalˆuh!jqh]rxhX The URL confry…rz}r{(hX The URL confr|h!juubah"hÎubah"hÏubah"háubh¼)r}}r~(hUh}r(h]h]h]h]h]uh!j9h]r€hÁ)r}r‚(hUh}rƒ(h]h]h]h]h]uh!j}h]r„hÆ)r…}r†(hUh}r‡(U anchornameU #the-templateUrefurih-h]h]h]h]h]Uinternalˆuh!jh]rˆhX The templater‰…rŠ}r‹(hX The templaterŒh!j…ubah"hÎubah"hÏubah"háubh¼)r}rŽ(hUh}r(h]h]h]h]h]uh!j9h]r(hÁ)r‘}r’(hUh}r“(h]h]h]h]h]uh!jh]r”hÆ)r•}r–(hUh}r—(U anchornameU#other-meta-optionsUrefurih-h]h]h]h]h]Uinternalˆuh!j‘h]r˜hXOther Meta optionsr™…rš}r›(hXOther Meta optionsrœh!j•ubah"hÎubah"hÏubh·)r}rž(hUh}rŸ(h]h]h]h]h]uh!jh]r (h¼)r¡}r¢(hUh}r£(h]h]h]h]h]uh!jh]r¤hÁ)r¥}r¦(hUh}r§(h]h]h]h]h]uh!j¡h]r¨hÆ)r©}rª(hUh}r«(U anchornameU#ordering-using-order-byUrefurih-h]h]h]h]h]Uinternalˆuh!j¥h]r¬(hXOrdering using r­…r®}r¯(hXOrdering using r°h!j©ubcdocutils.nodes literal r±)r²}r³(hX ``order_by``r´h}rµ(h]h]h]h]h]uh!j©h]r¶hXorder_byr·…r¸}r¹(hUh!j²ubah"Uliteralrºubeh"hÎubah"hÏubah"háubh¼)r»}r¼(hUh}r½(h]h]h]h]h]uh!jh]r¾hÁ)r¿}rÀ(hUh}rÁ(h]h]h]h]h]uh!j»h]rÂhÆ)rÃ}rÄ(hUh}rÅ(U anchornameU#custom-forms-using-formUrefurih-h]h]h]h]h]Uinternalˆuh!j¿h]rÆ(hXCustom Forms using rÇ…rÈ}rÉ(hXCustom Forms using rÊh!jÃubj±)rË}rÌ(hX``form``rÍh}rÎ(h]h]h]h]h]uh!jÃh]rÏhXformrÐ…rÑ}rÒ(hUh!jËubah"jºubeh"hÎubah"hÏubah"háubeh"hàubeh"háubh¼)rÓ}rÔ(hUh}rÕ(h]h]h]h]h]uh!j9h]rÖ(hÁ)r×}rØ(hUh}rÙ(h]h]h]h]h]uh!jÓh]rÚhÆ)rÛ}rÜ(hUh}rÝ(U anchornameU#non-meta-optionsUrefurih-h]h]h]h]h]Uinternalˆuh!j×h]rÞhXNon-Meta optionsrß…rà}rá(hXNon-Meta optionsrâh!jÛubah"hÎubah"hÏubh·)rã}rä(hUh}rå(h]h]h]h]h]uh!jÓh]ræh¼)rç}rè(hUh}ré(h]h]h]h]h]uh!jãh]rêhÁ)rë}rì(hUh}rí(h]h]h]h]h]uh!jçh]rîhÆ)rï}rð(hUh}rñ(U anchornameU#strictUrefurih-h]h]h]h]h]Uinternalˆuh!jëh]ròj±)ró}rô(hX ``strict``rõh}rö(h]h]h]h]h]uh!jïh]r÷hXstrictrø…rù}rú(hUh!jóubah"jºubah"hÎubah"hÏubah"háubah"hàubeh"háubh¼)rû}rü(hUh}rý(h]h]h]h]h]uh!j9h]rþ(hÁ)rÿ}r(hUh}r(h]h]h]h]h]uh!jûh]rhÆ)r}r(hUh}r(U anchornameU#overriding-filterset-methodsUrefurih-h]h]h]h]h]Uinternalˆuh!jÿh]r(hX Overriding r…r}r (hX Overriding r h!jubj±)r }r (hX ``FilterSet``r h}r(h]h]h]h]h]uh!jh]rhX FilterSetr…r}r(hUh!j ubah"jºubhX methodsr…r}r(hX methodsrh!jubeh"hÎubah"hÏubh·)r}r(hUh}r(h]h]h]h]h]uh!jûh]rh¼)r}r(hUh}r(h]h]h]h]h]uh!jh]rhÁ)r}r (hUh}r!(h]h]h]h]h]uh!jh]r"hÆ)r#}r$(hUh}r%(U anchornameU#get-ordering-fieldUrefurih-h]h]h]h]h]Uinternalˆuh!jh]r&j±)r'}r((hX``get_ordering_field()``r)h}r*(h]h]h]h]h]uh!j#h]r+hXget_ordering_field()r,…r-}r.(hUh!j'ubah"jºubah"hÎubah"hÏubah"háubah"hàubeh"háubh¼)r/}r0(hUh}r1(h]h]h]h]h]uh!j9h]r2hÁ)r3}r4(hUh}r5(h]h]h]h]h]uh!j/h]r6hÆ)r7}r8(hUh}r9(U anchornameU #generic-viewUrefurih-h]h]h]h]h]Uinternalˆuh!j3h]r:hX Generic Viewr;…r<}r=(hX Generic Viewr>h!j7ubah"hÎubah"hÏubah"háubeh"hàubeh"háubah"hàubh6h·)r?}r@(hUh}rA(h]h]h]h]h]uh]rBh¼)rC}rD(hUh}rE(h]h]h]h]h]uh!j?h]rF(hÁ)rG}rH(hUh}rI(h]h]h]h]h]uh!jCh]rJhÆ)rK}rL(hUh}rM(U anchornameUUrefurih6h]h]h]h]h]Uinternalˆuh!jGh]rNhXWidget ReferencerO…rP}rQ(hh>h!jKubah"hÎubah"hÏubh·)rR}rS(hUh}rT(h]h]h]h]h]uh!jCh]rUh¼)rV}rW(hUh}rX(h]h]h]h]h]uh!jRh]rYhÁ)rZ}r[(hUh}r\(h]h]h]h]h]uh!jVh]r]hÆ)r^}r_(hUh}r`(U anchornameU #linkwidgetUrefurih6h]h]h]h]h]Uinternalˆuh!jZh]raj±)rb}rc(hX``LinkWidget``h}rd(h]h]h]h]h]uh!j^h]rehX LinkWidgetrf…rg}rh(hUh!jbubah"jºubah"hÎubah"hÏubah"háubah"hàubeh"háubah"hàubh?h·)ri}rj(hUh}rk(h]h]h]h]h]uh]rlh¼)rm}rn(hUh}ro(h]h]h]h]h]uh!jih]rphÁ)rq}rr(hUh}rs(h]h]h]h]h]uh!jmh]rthÆ)ru}rv(hUh}rw(U anchornameUUrefurih?h]h]h]h]h]Uinternalˆuh!jqh]rxhXInstalling django-filterry…rz}r{(hhGh!juubah"hÎubah"hÏubah"háubah"hàubhHh·)r|}r}(hUh}r~(h]h]h]h]h]uh]rh¼)r€}r(hUh}r‚(h]h]h]h]h]uh!j|h]rƒ(hÁ)r„}r…(hUh}r†(h]h]h]h]h]uh!j€h]r‡hÆ)rˆ}r‰(hUh}rŠ(U anchornameUUrefurihHh]h]h]h]h]Uinternalˆuh!j„h]r‹hXFilter ReferencerŒ…r}rŽ(hhPh!jˆubah"hÎubah"hÏubh·)r}r(hUh}r‘(h]h]h]h]h]uh!j€h]r’(h¼)r“}r”(hUh}r•(h]h]h]h]h]uh!jh]r–(hÁ)r—}r˜(hUh}r™(h]h]h]h]h]uh!j“h]ršhÆ)r›}rœ(hUh}r(U anchornameU#filtersUrefurihHh]h]h]h]h]Uinternalˆuh!j—h]ržhXFiltersrŸ…r }r¡(hXFiltersr¢h!j›ubah"hÎubah"hÏubh·)r£}r¤(hUh}r¥(h]h]h]h]h]uh!j“h]r¦(h¼)r§}r¨(hUh}r©(h]h]h]h]h]uh!j£h]rªhÁ)r«}r¬(hUh}r­(h]h]h]h]h]uh!j§h]r®hÆ)r¯}r°(hUh}r±(U anchornameU #charfilterUrefurihHh]h]h]h]h]Uinternalˆuh!j«h]r²j±)r³}r´(hX``CharFilter``rµh}r¶(h]h]h]h]h]uh!j¯h]r·hX CharFilterr¸…r¹}rº(hUh!j³ubah"jºubah"hÎubah"hÏubah"háubh¼)r»}r¼(hUh}r½(h]h]h]h]h]uh!j£h]r¾hÁ)r¿}rÀ(hUh}rÁ(h]h]h]h]h]uh!j»h]rÂhÆ)rÃ}rÄ(hUh}rÅ(U anchornameU#booleanfilterUrefurihHh]h]h]h]h]Uinternalˆuh!j¿h]rÆj±)rÇ}rÈ(hX``BooleanFilter``rÉh}rÊ(h]h]h]h]h]uh!jÃh]rËhX BooleanFilterrÌ…rÍ}rÎ(hUh!jÇubah"jºubah"hÎubah"hÏubah"háubh¼)rÏ}rÐ(hUh}rÑ(h]h]h]h]h]uh!j£h]rÒhÁ)rÓ}rÔ(hUh}rÕ(h]h]h]h]h]uh!jÏh]rÖhÆ)r×}rØ(hUh}rÙ(U anchornameU #choicefilterUrefurihHh]h]h]h]h]Uinternalˆuh!jÓh]rÚj±)rÛ}rÜ(hX``ChoiceFilter``rÝh}rÞ(h]h]h]h]h]uh!j×h]rßhX ChoiceFilterrà…rá}râ(hUh!jÛubah"jºubah"hÎubah"hÏubah"háubh¼)rã}rä(hUh}rå(h]h]h]h]h]uh!j£h]ræhÁ)rç}rè(hUh}ré(h]h]h]h]h]uh!jãh]rêhÆ)rë}rì(hUh}rí(U anchornameU#typedchoicefilterUrefurihHh]h]h]h]h]Uinternalˆuh!jçh]rîj±)rï}rð(hX``TypedChoiceFilter``rñh}rò(h]h]h]h]h]uh!jëh]róhXTypedChoiceFilterrô…rõ}rö(hUh!jïubah"jºubah"hÎubah"hÏubah"háubh¼)r÷}rø(hUh}rù(h]h]h]h]h]uh!j£h]rúhÁ)rû}rü(hUh}rý(h]h]h]h]h]uh!j÷h]rþhÆ)rÿ}r(hUh}r(U anchornameU#multiplechoicefilterUrefurihHh]h]h]h]h]Uinternalˆuh!jûh]rj±)r}r(hX``MultipleChoiceFilter``rh}r(h]h]h]h]h]uh!jÿh]rhXMultipleChoiceFilterr…r }r (hUh!jubah"jºubah"hÎubah"hÏubah"háubh¼)r }r (hUh}r (h]h]h]h]h]uh!j£h]rhÁ)r}r(hUh}r(h]h]h]h]h]uh!j h]rhÆ)r}r(hUh}r(U anchornameU #datefilterUrefurihHh]h]h]h]h]Uinternalˆuh!jh]rj±)r}r(hX``DateFilter``rh}r(h]h]h]h]h]uh!jh]rhX DateFilterr…r}r(hUh!jubah"jºubah"hÎubah"hÏubah"háubh¼)r}r (hUh}r!(h]h]h]h]h]uh!j£h]r"hÁ)r#}r$(hUh}r%(h]h]h]h]h]uh!jh]r&hÆ)r'}r((hUh}r)(U anchornameU#datetimefilterUrefurihHh]h]h]h]h]Uinternalˆuh!j#h]r*j±)r+}r,(hX``DateTimeFilter``r-h}r.(h]h]h]h]h]uh!j'h]r/hXDateTimeFilterr0…r1}r2(hUh!j+ubah"jºubah"hÎubah"hÏubah"háubh¼)r3}r4(hUh}r5(h]h]h]h]h]uh!j£h]r6hÁ)r7}r8(hUh}r9(h]h]h]h]h]uh!j3h]r:hÆ)r;}r<(hUh}r=(U anchornameU #timefilterUrefurihHh]h]h]h]h]Uinternalˆuh!j7h]r>j±)r?}r@(hX``TimeFilter``rAh}rB(h]h]h]h]h]uh!j;h]rChX TimeFilterrD…rE}rF(hUh!j?ubah"jºubah"hÎubah"hÏubah"háubh¼)rG}rH(hUh}rI(h]h]h]h]h]uh!j£h]rJhÁ)rK}rL(hUh}rM(h]h]h]h]h]uh!jGh]rNhÆ)rO}rP(hUh}rQ(U anchornameU#modelchoicefilterUrefurihHh]h]h]h]h]Uinternalˆuh!jKh]rRj±)rS}rT(hX``ModelChoiceFilter``rUh}rV(h]h]h]h]h]uh!jOh]rWhXModelChoiceFilterrX…rY}rZ(hUh!jSubah"jºubah"hÎubah"hÏubah"háubh¼)r[}r\(hUh}r](h]h]h]h]h]uh!j£h]r^hÁ)r_}r`(hUh}ra(h]h]h]h]h]uh!j[h]rbhÆ)rc}rd(hUh}re(U anchornameU#modelmultiplechoicefilterUrefurihHh]h]h]h]h]Uinternalˆuh!j_h]rfj±)rg}rh(hX``ModelMultipleChoiceFilter``rih}rj(h]h]h]h]h]uh!jch]rkhXModelMultipleChoiceFilterrl…rm}rn(hUh!jgubah"jºubah"hÎubah"hÏubah"háubh¼)ro}rp(hUh}rq(h]h]h]h]h]uh!j£h]rrhÁ)rs}rt(hUh}ru(h]h]h]h]h]uh!joh]rvhÆ)rw}rx(hUh}ry(U anchornameU #numberfilterUrefurihHh]h]h]h]h]Uinternalˆuh!jsh]rzj±)r{}r|(hX``NumberFilter``r}h}r~(h]h]h]h]h]uh!jwh]rhX NumberFilterr€…r}r‚(hUh!j{ubah"jºubah"hÎubah"hÏubah"háubh¼)rƒ}r„(hUh}r…(h]h]h]h]h]uh!j£h]r†hÁ)r‡}rˆ(hUh}r‰(h]h]h]h]h]uh!jƒh]rŠhÆ)r‹}rŒ(hUh}r(U anchornameU #rangefilterUrefurihHh]h]h]h]h]Uinternalˆuh!j‡h]rŽj±)r}r(hX``RangeFilter``r‘h}r’(h]h]h]h]h]uh!j‹h]r“hX RangeFilterr”…r•}r–(hUh!jubah"jºubah"hÎubah"hÏubah"háubh¼)r—}r˜(hUh}r™(h]h]h]h]h]uh!j£h]ršhÁ)r›}rœ(hUh}r(h]h]h]h]h]uh!j—h]ržhÆ)rŸ}r (hUh}r¡(U anchornameU#daterangefilterUrefurihHh]h]h]h]h]Uinternalˆuh!j›h]r¢j±)r£}r¤(hX``DateRangeFilter``r¥h}r¦(h]h]h]h]h]uh!jŸh]r§hXDateRangeFilterr¨…r©}rª(hUh!j£ubah"jºubah"hÎubah"hÏubah"háubh¼)r«}r¬(hUh}r­(h]h]h]h]h]uh!j£h]r®hÁ)r¯}r°(hUh}r±(h]h]h]h]h]uh!j«h]r²hÆ)r³}r´(hUh}rµ(U anchornameU#allvaluesfilterUrefurihHh]h]h]h]h]Uinternalˆuh!j¯h]r¶j±)r·}r¸(hX``AllValuesFilter``r¹h}rº(h]h]h]h]h]uh!j³h]r»hXAllValuesFilterr¼…r½}r¾(hUh!j·ubah"jºubah"hÎubah"hÏubah"háubh¼)r¿}rÀ(hUh}rÁ(h]h]h]h]h]uh!j£h]rÂhÁ)rÃ}rÄ(hUh}rÅ(h]h]h]h]h]uh!j¿h]rÆhÆ)rÇ}rÈ(hUh}rÉ(U anchornameU #methodfilterUrefurihHh]h]h]h]h]Uinternalˆuh!jÃh]rÊj±)rË}rÌ(hX``MethodFilter``rÍh}rÎ(h]h]h]h]h]uh!jÇh]rÏhX MethodFilterrÐ…rÑ}rÒ(hUh!jËubah"jºubah"hÎubah"hÏubah"háubeh"hàubeh"háubh¼)rÓ}rÔ(hUh}rÕ(h]h]h]h]h]uh!jh]rÖ(hÁ)r×}rØ(hUh}rÙ(h]h]h]h]h]uh!jÓh]rÚhÆ)rÛ}rÜ(hUh}rÝ(U anchornameU#core-argumentsUrefurihHh]h]h]h]h]Uinternalˆuh!j×h]rÞhXCore Argumentsrß…rà}rá(hXCore Argumentsrâh!jÛubah"hÎubah"hÏubh·)rã}rä(hUh}rå(h]h]h]h]h]uh!jÓh]ræ(h¼)rç}rè(hUh}ré(h]h]h]h]h]uh!jãh]rêhÁ)rë}rì(hUh}rí(h]h]h]h]h]uh!jçh]rîhÆ)rï}rð(hUh}rñ(U anchornameU#nameUrefurihHh]h]h]h]h]Uinternalˆuh!jëh]ròj±)ró}rô(hX``name``rõh}rö(h]h]h]h]h]uh!jïh]r÷hXnamerø…rù}rú(hUh!jóubah"jºubah"hÎubah"hÏubah"háubh¼)rû}rü(hUh}rý(h]h]h]h]h]uh!jãh]rþhÁ)rÿ}r(hUh}r(h]h]h]h]h]uh!jûh]rhÆ)r}r(hUh}r(U anchornameU#labelUrefurihHh]h]h]h]h]Uinternalˆuh!jÿh]rj±)r}r(hX ``label``r h}r (h]h]h]h]h]uh!jh]r hXlabelr …r }r(hUh!jubah"jºubah"hÎubah"hÏubah"háubh¼)r}r(hUh}r(h]h]h]h]h]uh!jãh]rhÁ)r}r(hUh}r(h]h]h]h]h]uh!jh]rhÆ)r}r(hUh}r(U anchornameU#widgetUrefurihHh]h]h]h]h]Uinternalˆuh!jh]rj±)r}r(hX ``widget``rh}r(h]h]h]h]h]uh!jh]rhXwidgetr …r!}r"(hUh!jubah"jºubah"hÎubah"hÏubah"háubh¼)r#}r$(hUh}r%(h]h]h]h]h]uh!jãh]r&hÁ)r'}r((hUh}r)(h]h]h]h]h]uh!j#h]r*hÆ)r+}r,(hUh}r-(U anchornameU#actionUrefurihHh]h]h]h]h]Uinternalˆuh!j'h]r.j±)r/}r0(hX ``action``r1h}r2(h]h]h]h]h]uh!j+h]r3hXactionr4…r5}r6(hUh!j/ubah"jºubah"hÎubah"hÏubah"háubh¼)r7}r8(hUh}r9(h]h]h]h]h]uh!jãh]r:hÁ)r;}r<(hUh}r=(h]h]h]h]h]uh!j7h]r>hÆ)r?}r@(hUh}rA(U anchornameU #lookup-typeUrefurihHh]h]h]h]h]Uinternalˆuh!j;h]rBj±)rC}rD(hX``lookup_type``rEh}rF(h]h]h]h]h]uh!j?h]rGhX lookup_typerH…rI}rJ(hUh!jCubah"jºubah"hÎubah"hÏubah"háubh¼)rK}rL(hUh}rM(h]h]h]h]h]uh!jãh]rNhÁ)rO}rP(hUh}rQ(h]h]h]h]h]uh!jKh]rRhÆ)rS}rT(hUh}rU(U anchornameU #distinctUrefurihHh]h]h]h]h]Uinternalˆuh!jOh]rVj±)rW}rX(hX ``distinct``rYh}rZ(h]h]h]h]h]uh!jSh]r[hXdistinctr\…r]}r^(hUh!jWubah"jºubah"hÎubah"hÏubah"háubh¼)r_}r`(hUh}ra(h]h]h]h]h]uh!jãh]rbhÁ)rc}rd(hUh}re(h]h]h]h]h]uh!j_h]rfhÆ)rg}rh(hUh}ri(U anchornameU#excludeUrefurihHh]h]h]h]h]Uinternalˆuh!jch]rjj±)rk}rl(hX ``exclude``rmh}rn(h]h]h]h]h]uh!jgh]rohXexcluderp…rq}rr(hUh!jkubah"jºubah"hÎubah"hÏubah"háubh¼)rs}rt(hUh}ru(h]h]h]h]h]uh!jãh]rvhÁ)rw}rx(hUh}ry(h]h]h]h]h]uh!jsh]rzhÆ)r{}r|(hUh}r}(U anchornameU#kwargsUrefurihHh]h]h]h]h]Uinternalˆuh!jwh]r~j±)r}r€(hX ``**kwargs``rh}r‚(h]h]h]h]h]uh!j{h]rƒhX**kwargsr„…r…}r†(hUh!jubah"jºubah"hÎubah"hÏubah"háubeh"hàubeh"háubeh"hàubeh"háubah"hàubuU indexentriesr‡}rˆ(h]h$]h-]h6]h?]hH]uUall_docsr‰}rŠ(hGAÕ7'q¹h$GAÕ7+•_h-GAÕ7-+íh6GAÕ7*ûjh?GAÕ7'ØùhHGAÕ7)ãuUsettingsr‹}rŒ(Ucloak_email_addressesˆUtrim_footnote_reference_space‰U halt_levelKUsectsubtitle_xform‰Uembed_stylesheet‰U pep_base_urlUhttp://www.python.org/dev/peps/rUdoctitle_xform‰Uwarning_streamcsphinx.util.nodes WarningStream rŽ)r}r(U_rer‘cre _compile r’U+\((DEBUG|INFO|WARNING|ERROR|SEVERE)/[0-4]\)r“K†Rr”Uwarnfuncr•NubUenvhU rfc_base_urlUhttp://tools.ietf.org/html/r–Ufile_insertion_enabledˆUgettext_compactˆUinput_encodingU utf-8-sigr—uUfiles_to_rebuildr˜}r™(h°h]ršha…Rr›h±h]rœha…Rrh²h]ržha…RrŸh³h]r ha…Rr¡h¯h]r¢ha…Rr£uUtoc_secnumbersr¤}U_nitpick_ignorer¥h]…Rr¦U _warnfuncr§Nub.django-filter-0.11.0/docs/_build/doctrees/index.doctree0000644000076500000240000000675412436054334023577 0ustar carltonstaff00000000000000€cdocutils.nodes document q)q}q(U nametypesq}qX django-filterqNsUsubstitution_defsq}qUparse_messagesq ]q Ucurrent_sourceq NU decorationq NUautofootnote_startq KUnameidsq}qhU django-filterqsUchildrenq]qcdocutils.nodes section q)q}q(U rawsourceqUUparentqhUsourceqXB/Users/carlton/Documents/Django-Stack/django-filter/docs/index.txtqUtagnameqUsectionqU attributesq}q(Udupnamesq]Uclassesq]Ubackrefsq ]Uidsq!]q"haUnamesq#]q$hauUlineq%KUdocumentq&hh]q'(cdocutils.nodes title q()q)}q*(hX django-filterq+hhhhhUtitleq,h}q-(h]h]h ]h!]h#]uh%Kh&hh]q.cdocutils.nodes Text q/X django-filterq0…q1}q2(hh+hh)ubaubcdocutils.nodes paragraph q3)q4}q5(hXíDjango-filter is a generic, reusable application to alleviate writing some of the more mundane bits of view code. Specifically, it allows users to filter down a queryset based on a model's fields, displaying the form to let them do this.q6hhhhhU paragraphq7h}q8(h]h]h ]h!]h#]uh%Kh&hh]q9h/XíDjango-filter is a generic, reusable application to alleviate writing some of the more mundane bits of view code. Specifically, it allows users to filter down a queryset based on a model's fields, displaying the form to let them do this.q:…q;}q<(hh6hh4ubaubh3)q=}q>(hX Contents:q?hhhhhh7h}q@(h]h]h ]h!]h#]uh%K h&hh]qAh/X Contents:qB…qC}qD(hh?hh=ubaubcdocutils.nodes compound qE)qF}qG(hUhhhhhUcompoundqHh}qI(h]h]qJUtoctree-wrapperqKah ]h!]h#]uh%Nh&hh]qLcsphinx.addnodes toctree qM)qN}qO(hUhhFhhhUtoctreeqPh}qQ(UnumberedqRKU includehiddenqS‰hXindexqTU titlesonlyqU‰UglobqV‰h!]h ]h]h]h#]UentriesqW]qX(NXinstallqY†qZNXusageq[†q\NX ref/filtersq]†q^NX ref/widgetsq_†q`NXtestsqa†qbeUhiddenqc‰U includefilesqd]qe(hYh[h]h_haeUmaxdepthqfKuh%K h]ubaubeubahUU transformerqgNU footnote_refsqh}qiUrefnamesqj}qkUsymbol_footnotesql]qmUautofootnote_refsqn]qoUsymbol_footnote_refsqp]qqU citationsqr]qsh&hU current_lineqtNUtransform_messagesqu]qvUreporterqwNUid_startqxKU autofootnotesqy]qzU citation_refsq{}q|Uindirect_targetsq}]q~Usettingsq(cdocutils.frontend Values q€oq}q‚(Ufootnote_backlinksqƒKUrecord_dependenciesq„NU rfc_base_urlq…Uhttp://tools.ietf.org/html/q†U tracebackq‡ˆUpep_referencesqˆNUstrip_commentsq‰NU toc_backlinksqŠUentryq‹U language_codeqŒUenqU datestampqŽNU report_levelqKU _destinationqNU halt_levelq‘KU strip_classesq’Nh,NUerror_encoding_error_handlerq“Ubackslashreplaceq”Udebugq•NUembed_stylesheetq–‰Uoutput_encoding_error_handlerq—Ustrictq˜U sectnum_xformq™KUdump_transformsqšNU docinfo_xformq›KUwarning_streamqœNUpep_file_url_templateqUpep-%04dqžUexit_status_levelqŸKUconfigq NUstrict_visitorq¡NUcloak_email_addressesq¢ˆUtrim_footnote_reference_spaceq£‰Uenvq¤NUdump_pseudo_xmlq¥NUexpose_internalsq¦NUsectsubtitle_xformq§‰U source_linkq¨NUrfc_referencesq©NUoutput_encodingqªUutf-8q«U source_urlq¬NUinput_encodingq­U utf-8-sigq®U_disable_configq¯NU id_prefixq°UU tab_widthq±KUerror_encodingq²UUTF-8q³U_sourceq´hUgettext_compactqµˆU generatorq¶NUdump_internalsq·NU smart_quotesq¸‰U pep_base_urlq¹Uhttp://www.python.org/dev/peps/qºUsyntax_highlightq»Ulongq¼Uinput_encoding_error_handlerq½h˜Uauto_id_prefixq¾Uidq¿Udoctitle_xformqÀ‰Ustrip_elements_with_classesqÁNU _config_filesqÂ]qÃUfile_insertion_enabledqĈU raw_enabledqÅKU dump_settingsqÆNubUsymbol_footnote_startqÇKUidsqÈ}qÉhhsUsubstitution_namesqÊ}qËhh&h}qÌ(h]h!]h ]Usourcehh]h#]uU footnotesqÍ]qÎUrefidsqÏ}qÐub.django-filter-0.11.0/docs/_build/doctrees/install.doctree0000644000076500000240000000665112436054334024132 0ustar carltonstaff00000000000000€cdocutils.nodes document q)q}q(U nametypesq}qXinstalling django-filterqNsUsubstitution_defsq}qUparse_messagesq ]q Ucurrent_sourceq NU decorationq NUautofootnote_startq KUnameidsq}qhUinstalling-django-filterqsUchildrenq]qcdocutils.nodes section q)q}q(U rawsourceqUUparentqhUsourceqXD/Users/carlton/Documents/Django-Stack/django-filter/docs/install.txtqUtagnameqUsectionqU attributesq}q(Udupnamesq]Uclassesq]Ubackrefsq ]Uidsq!]q"haUnamesq#]q$hauUlineq%KUdocumentq&hh]q'(cdocutils.nodes title q()q)}q*(hXInstalling django-filterq+hhhhhUtitleq,h}q-(h]h]h ]h!]h#]uh%Kh&hh]q.cdocutils.nodes Text q/XInstalling django-filterq0…q1}q2(hh+hh)ubaubcdocutils.nodes paragraph q3)q4}q5(hX™To install, simply place the ``django_filters`` directory somewhere on your ``PYTHONPATH``, and then add ``'django_filters'`` to your ``INSTALLED_APPS``.hhhhhU paragraphq6h}q7(h]h]h ]h!]h#]uh%Kh&hh]q8(h/XTo install, simply place the q9…q:}q;(hXTo install, simply place the hh4ubcdocutils.nodes literal q<)q=}q>(hX``django_filters``h}q?(h]h]h ]h!]h#]uhh4h]q@h/Xdjango_filtersqA…qB}qC(hUhh=ubahUliteralqDubh/X directory somewhere on your qE…qF}qG(hX directory somewhere on your hh4ubh<)qH}qI(hX``PYTHONPATH``h}qJ(h]h]h ]h!]h#]uhh4h]qKh/X PYTHONPATHqL…qM}qN(hUhhHubahhDubh/X, and then add qO…qP}qQ(hX, and then add hh4ubh<)qR}qS(hX``'django_filters'``h}qT(h]h]h ]h!]h#]uhh4h]qUh/X'django_filters'qV…qW}qX(hUhhRubahhDubh/X to your qY…qZ}q[(hX to your hh4ubh<)q\}q](hX``INSTALLED_APPS``h}q^(h]h]h ]h!]h#]uhh4h]q_h/XINSTALLED_APPSq`…qa}qb(hUhh\ubahhDubh/X.…qc}qd(hX.hh4ubeubeubahUU transformerqeNU footnote_refsqf}qgUrefnamesqh}qiUsymbol_footnotesqj]qkUautofootnote_refsql]qmUsymbol_footnote_refsqn]qoU citationsqp]qqh&hU current_lineqrNUtransform_messagesqs]qtUreporterquNUid_startqvKU autofootnotesqw]qxU citation_refsqy}qzUindirect_targetsq{]q|Usettingsq}(cdocutils.frontend Values q~oq}q€(Ufootnote_backlinksqKUrecord_dependenciesq‚NU rfc_base_urlqƒUhttp://tools.ietf.org/html/q„U tracebackq…ˆUpep_referencesq†NUstrip_commentsq‡NU toc_backlinksqˆUentryq‰U language_codeqŠUenq‹U datestampqŒNU report_levelqKU _destinationqŽNU halt_levelqKU strip_classesqNh,NUerror_encoding_error_handlerq‘Ubackslashreplaceq’Udebugq“NUembed_stylesheetq”‰Uoutput_encoding_error_handlerq•Ustrictq–U sectnum_xformq—KUdump_transformsq˜NU docinfo_xformq™KUwarning_streamqšNUpep_file_url_templateq›Upep-%04dqœUexit_status_levelqKUconfigqžNUstrict_visitorqŸNUcloak_email_addressesq ˆUtrim_footnote_reference_spaceq¡‰Uenvq¢NUdump_pseudo_xmlq£NUexpose_internalsq¤NUsectsubtitle_xformq¥‰U source_linkq¦NUrfc_referencesq§NUoutput_encodingq¨Uutf-8q©U source_urlqªNUinput_encodingq«U utf-8-sigq¬U_disable_configq­NU id_prefixq®UU tab_widthq¯KUerror_encodingq°UUTF-8q±U_sourceq²hUgettext_compactq³ˆU generatorq´NUdump_internalsqµNU smart_quotesq¶‰U pep_base_urlq·Uhttp://www.python.org/dev/peps/q¸Usyntax_highlightq¹UlongqºUinput_encoding_error_handlerq»h–Uauto_id_prefixq¼Uidq½Udoctitle_xformq¾‰Ustrip_elements_with_classesq¿NU _config_filesqÀ]Ufile_insertion_enabledqÁˆU raw_enabledqÂKU dump_settingsqÃNubUsymbol_footnote_startqÄKUidsqÅ}qÆhhsUsubstitution_namesqÇ}qÈhh&h}qÉ(h]h!]h ]Usourcehh]h#]uU footnotesqÊ]qËUrefidsqÌ}qÍub.django-filter-0.11.0/docs/_build/doctrees/ref/0000755000076500000240000000000012563340512021656 5ustar carltonstaff00000000000000django-filter-0.11.0/docs/_build/doctrees/ref/filters.doctree0000644000076500000240000010651312436054334024706 0ustar carltonstaff00000000000000€cdocutils.nodes document q)q}q(U nametypesq}q(XdaterangefilterqNXallvaluesfilterqNX numberfilterqNXdatetimefilterq NXfiltersq NXexcludeq NXdistinctq NXlabelq NXfilter referenceqNXwidgetqNX timefilterqNX rangefilterqNXmodelchoicefilterqNX choicefilterqNX**kwargsqNXnameqNXtypedchoicefilterqNXcore argumentsqNXmodelmultiplechoicefilterqNXmultiplechoicefilterqNX datefilterqNX lookup_typeqNX charfilterqNX booleanfilterqNXactionqNX methodfilterqNuUsubstitution_defsq }q!Uparse_messagesq"]q#Ucurrent_sourceq$NU decorationq%NUautofootnote_startq&KUnameidsq'}q((hUdaterangefilterq)hUallvaluesfilterq*hU numberfilterq+h Udatetimefilterq,h Ufiltersq-h Uexcludeq.h Udistinctq/h Ulabelq0hUfilter-referenceq1hUwidgetq2hU timefilterq3hU rangefilterq4hUmodelchoicefilterq5hU choicefilterq6hUkwargsq7hUnameq8hUtypedchoicefilterq9hUcore-argumentsq:hUmodelmultiplechoicefilterq;hUmultiplechoicefilterqhU charfilterq?hU booleanfilterq@hUactionqAhU methodfilterqBuUchildrenqC]qDcdocutils.nodes section qE)qF}qG(U rawsourceqHUUparentqIhUsourceqJXH/Users/carlton/Documents/Django-Stack/django-filter/docs/ref/filters.txtqKUtagnameqLUsectionqMU attributesqN}qO(UdupnamesqP]UclassesqQ]UbackrefsqR]UidsqS]qTh1aUnamesqU]qVhauUlineqWKUdocumentqXhhC]qY(cdocutils.nodes title qZ)q[}q\(hHXFilter Referenceq]hIhFhJhKhLUtitleq^hN}q_(hP]hQ]hR]hS]hU]uhWKhXhhC]q`cdocutils.nodes Text qaXFilter Referenceqb…qc}qd(hHh]hIh[ubaubcdocutils.nodes paragraph qe)qf}qg(hHXLThis is a reference document with a list of the filters and their arguments.qhhIhFhJhKhLU paragraphqihN}qj(hP]hQ]hR]hS]hU]uhWKhXhhC]qkhaXLThis is a reference document with a list of the filters and their arguments.ql…qm}qn(hHhhhIhfubaubhE)qo}qp(hHUhIhFhJhKhLhMhN}qq(hP]hQ]hR]hS]qrh-ahU]qsh auhWKhXhhC]qt(hZ)qu}qv(hHXFiltersqwhIhohJhKhLh^hN}qx(hP]hQ]hR]hS]hU]uhWKhXhhC]qyhaXFiltersqz…q{}q|(hHhwhIhuubaubhE)q}}q~(hHUhIhohJhKhLhMhN}q(hP]hQ]hR]hS]q€h?ahU]qhauhWK hXhhC]q‚(hZ)qƒ}q„(hHX``CharFilter``q…hIh}hJhKhLh^hN}q†(hP]hQ]hR]hS]hU]uhWK hXhhC]q‡cdocutils.nodes literal qˆ)q‰}qŠ(hHh…hN}q‹(hP]hQ]hR]hS]hU]uhIhƒhC]qŒhaX CharFilterq…qŽ}q(hHUhIh‰ubahLUliteralqubaubhe)q‘}q’(hHX`This filter does simple character matches, used with ``CharField`` and ``TextField`` by default.hIh}hJhKhLhihN}q“(hP]hQ]hR]hS]hU]uhWK hXhhC]q”(haX5This filter does simple character matches, used with q•…q–}q—(hHX5This filter does simple character matches, used with hIh‘ubhˆ)q˜}q™(hHX ``CharField``hN}qš(hP]hQ]hR]hS]hU]uhIh‘hC]q›haX CharFieldqœ…q}qž(hHUhIh˜ubahLhubhaX and qŸ…q }q¡(hHX and hIh‘ubhˆ)q¢}q£(hHX ``TextField``hN}q¤(hP]hQ]hR]hS]hU]uhIh‘hC]q¥haX TextFieldq¦…q§}q¨(hHUhIh¢ubahLhubhaX by default.q©…qª}q«(hHX by default.hIh‘ubeubeubhE)q¬}q­(hHUhIhohJhKhLhMhN}q®(hP]hQ]hR]hS]q¯h@ahU]q°hauhWKhXhhC]q±(hZ)q²}q³(hHX``BooleanFilter``q´hIh¬hJhKhLh^hN}qµ(hP]hQ]hR]hS]hU]uhWKhXhhC]q¶hˆ)q·}q¸(hHh´hN}q¹(hP]hQ]hR]hS]hU]uhIh²hC]qºhaX BooleanFilterq»…q¼}q½(hHUhIh·ubahLhubaubhe)q¾}q¿(hHX|This filter matches a boolean, either ``True`` or ``False``, used with ``BooleanField`` and ``NullBooleanField`` by default.hIh¬hJhKhLhihN}qÀ(hP]hQ]hR]hS]hU]uhWKhXhhC]qÁ(haX&This filter matches a boolean, either qÂ…qÃ}qÄ(hHX&This filter matches a boolean, either hIh¾ubhˆ)qÅ}qÆ(hHX``True``hN}qÇ(hP]hQ]hR]hS]hU]uhIh¾hC]qÈhaXTrueqÉ…qÊ}qË(hHUhIhÅubahLhubhaX or qÌ…qÍ}qÎ(hHX or hIh¾ubhˆ)qÏ}qÐ(hHX ``False``hN}qÑ(hP]hQ]hR]hS]hU]uhIh¾hC]qÒhaXFalseqÓ…qÔ}qÕ(hHUhIhÏubahLhubhaX , used with qÖ…q×}qØ(hHX , used with hIh¾ubhˆ)qÙ}qÚ(hHX``BooleanField``hN}qÛ(hP]hQ]hR]hS]hU]uhIh¾hC]qÜhaX BooleanFieldqÝ…qÞ}qß(hHUhIhÙubahLhubhaX and qà…qá}qâ(hHX and hIh¾ubhˆ)qã}qä(hHX``NullBooleanField``hN}qå(hP]hQ]hR]hS]hU]uhIh¾hC]qæhaXNullBooleanFieldqç…qè}qé(hHUhIhãubahLhubhaX by default.qê…që}qì(hHX by default.hIh¾ubeubeubhE)qí}qî(hHUhIhohJhKhLhMhN}qï(hP]hQ]hR]hS]qðh6ahU]qñhauhWKhXhhC]qò(hZ)qó}qô(hHX``ChoiceFilter``qõhIhíhJhKhLh^hN}qö(hP]hQ]hR]hS]hU]uhWKhXhhC]q÷hˆ)qø}qù(hHhõhN}qú(hP]hQ]hR]hS]hU]uhIhóhC]qûhaX ChoiceFilterqü…qý}qþ(hHUhIhøubahLhubaubhe)qÿ}r(hHX]This filter matches an item of any type by choices, used with any field that has ``choices``.hIhíhJhKhLhihN}r(hP]hQ]hR]hS]hU]uhWKhXhhC]r(haXQThis filter matches an item of any type by choices, used with any field that has r…r}r(hHXQThis filter matches an item of any type by choices, used with any field that has hIhÿubhˆ)r}r(hHX ``choices``hN}r(hP]hQ]hR]hS]hU]uhIhÿhC]r haXchoicesr …r }r (hHUhIjubahLhubhaX.…r }r(hHX.hIhÿubeubeubhE)r}r(hHUhIhohJhKhLhMhN}r(hP]hQ]hR]hS]rh9ahU]rhauhWKhXhhC]r(hZ)r}r(hHX``TypedChoiceFilter``rhIjhJhKhLh^hN}r(hP]hQ]hR]hS]hU]uhWKhXhhC]rhˆ)r}r(hHjhN}r(hP]hQ]hR]hS]hU]uhIjhC]rhaXTypedChoiceFilterr…r}r (hHUhIjubahLhubaubhe)r!}r"(hHXThe same as ``ChoiceFilter`` with the added possibility to convert value to match against. This could be done by using `coerce` parameter. An example use-case is limiting boolean choices to match against so only some predefined strings could be used as input of a boolean filter::hIjhJhKhLhihN}r#(hP]hQ]hR]hS]hU]uhWKhXhhC]r$(haX The same as r%…r&}r'(hHX The same as hIj!ubhˆ)r(}r)(hHX``ChoiceFilter``hN}r*(hP]hQ]hR]hS]hU]uhIj!hC]r+haX ChoiceFilterr,…r-}r.(hHUhIj(ubahLhubhaX[ with the added possibility to convert value to match against. This could be done by using r/…r0}r1(hHX[ with the added possibility to convert value to match against. This could be done by using hIj!ubcdocutils.nodes title_reference r2)r3}r4(hHX`coerce`hN}r5(hP]hQ]hR]hS]hU]uhIj!hC]r6haXcoercer7…r8}r9(hHUhIj3ubahLUtitle_referencer:ubhaX˜ parameter. An example use-case is limiting boolean choices to match against so only some predefined strings could be used as input of a boolean filter:r;…r<}r=(hHX˜ parameter. An example use-case is limiting boolean choices to match against so only some predefined strings could be used as input of a boolean filter:hIj!ubeubcdocutils.nodes literal_block r>)r?}r@(hHX0import django_filters from distutils.util import strtobool BOOLEAN_CHOICES = (('false', 'False'), ('true', 'True'),) class YourFilterSet(django_filters.FilterSet): ... flag = django_filters.TypedChoiceFilter(choices=BOOLEAN_CHOICES, coerce=strtobool)hIjhJhKhLU literal_blockrAhN}rB(U xml:spacerCUpreserverDhS]hR]hP]hQ]hU]uhWK#hXhhC]rEhaX0import django_filters from distutils.util import strtobool BOOLEAN_CHOICES = (('false', 'False'), ('true', 'True'),) class YourFilterSet(django_filters.FilterSet): ... flag = django_filters.TypedChoiceFilter(choices=BOOLEAN_CHOICES, coerce=strtobool)rF…rG}rH(hHUhIj?ubaubeubhE)rI}rJ(hHUhIhohJhKhLhMhN}rK(hP]hQ]hR]hS]rLh}r?(hHUhIj9ubahLhubhaX by default.r@…rA}rB(hHX by default.hIj(ubeubeubhE)rC}rD(hHUhIhohJhKhLhMhN}rE(hP]hQ]hR]hS]rFh;ahU]rGhauhWKThXhhC]rH(hZ)rI}rJ(hHX``ModelMultipleChoiceFilter``rKhIjChJhKhLh^hN}rL(hP]hQ]hR]hS]hU]uhWKThXhhC]rMhˆ)rN}rO(hHjKhN}rP(hP]hQ]hR]hS]hU]uhIjIhC]rQhaXModelMultipleChoiceFilterrR…rS}rT(hHUhIjNubahLhubaubhe)rU}rV(hHXsSimilar to a ``MultipleChoiceFilter`` except it works with related models, used for ``ManyToManyField`` by default.hIjChJhKhLhihN}rW(hP]hQ]hR]hS]hU]uhWKVhXhhC]rX(haX Similar to a rY…rZ}r[(hHX Similar to a hIjUubhˆ)r\}r](hHX``MultipleChoiceFilter``hN}r^(hP]hQ]hR]hS]hU]uhIjUhC]r_haXMultipleChoiceFilterr`…ra}rb(hHUhIj\ubahLhubhaX/ except it works with related models, used for rc…rd}re(hHX/ except it works with related models, used for hIjUubhˆ)rf}rg(hHX``ManyToManyField``hN}rh(hP]hQ]hR]hS]hU]uhIjUhC]rihaXManyToManyFieldrj…rk}rl(hHUhIjfubahLhubhaX by default.rm…rn}ro(hHX by default.hIjUubeubeubhE)rp}rq(hHUhIhohJhKhLhMhN}rr(hP]hQ]hR]hS]rsh+ahU]rthauhWKZhXhhC]ru(hZ)rv}rw(hHX``NumberFilter``rxhIjphJhKhLh^hN}ry(hP]hQ]hR]hS]hU]uhWKZhXhhC]rzhˆ)r{}r|(hHjxhN}r}(hP]hQ]hR]hS]hU]uhIjvhC]r~haX NumberFilterr…r€}r(hHUhIj{ubahLhubaubhe)r‚}rƒ(hHXpFilters based on a numerical value, used with ``IntegerField``, ``FloatField``, and ``DecimalField`` by default.hIjphJhKhLhihN}r„(hP]hQ]hR]hS]hU]uhWK\hXhhC]r…(haX.Filters based on a numerical value, used with r†…r‡}rˆ(hHX.Filters based on a numerical value, used with hIj‚ubhˆ)r‰}rŠ(hHX``IntegerField``hN}r‹(hP]hQ]hR]hS]hU]uhIj‚hC]rŒhaX IntegerFieldr…rŽ}r(hHUhIj‰ubahLhubhaX, r…r‘}r’(hHX, hIj‚ubhˆ)r“}r”(hHX``FloatField``hN}r•(hP]hQ]hR]hS]hU]uhIj‚hC]r–haX FloatFieldr—…r˜}r™(hHUhIj“ubahLhubhaX, and rš…r›}rœ(hHX, and hIj‚ubhˆ)r}rž(hHX``DecimalField``hN}rŸ(hP]hQ]hR]hS]hU]uhIj‚hC]r haX DecimalFieldr¡…r¢}r£(hHUhIjubahLhubhaX by default.r¤…r¥}r¦(hHX by default.hIj‚ubeubeubhE)r§}r¨(hHUhIhohJhKhLhMhN}r©(hP]hQ]hR]hS]rªh4ahU]r«hauhWK`hXhhC]r¬(hZ)r­}r®(hHX``RangeFilter``r¯hIj§hJhKhLh^hN}r°(hP]hQ]hR]hS]hU]uhWK`hXhhC]r±hˆ)r²}r³(hHj¯hN}r´(hP]hQ]hR]hS]hU]uhIj­hC]rµhaX RangeFilterr¶…r·}r¸(hHUhIj²ubahLhubaubhe)r¹}rº(hHX’Filters where a value is between two numerical values, or greater than a minimum or less than a maximum where only one limit value is provided. ::r»hIj§hJhKhLhihN}r¼(hP]hQ]hR]hS]hU]uhWKbhXhhC]r½haXFilters where a value is between two numerical values, or greater than a minimum or less than a maximum where only one limit value is provided.r¾…r¿}rÀ(hHXFilters where a value is between two numerical values, or greater than a minimum or less than a maximum where only one limit value is provided.hIj¹ubaubj>)rÁ}rÂ(hHX»class F(FilterSet): """Filter for Books by Price""" price = RangeFilter() class Meta: model = Book fields = ['price'] qs = Book.objects.all().order_by('title') # Range: Books between 5€ and 15€ f = F({'price_0': '5', 'price_1': '15'}, queryset=qs) # Min-Only: Books costing more the 11€ f = F({'price_0': '11'}, queryset=qs) # Max-Only: Books costing less than 19€ f = F({'price_1': '19'}, queryset=qs)hIj§hJhKhLjAhN}rÃ(jCjDhS]hR]hP]hQ]hU]uhWKdhXhhC]rÄhaX»class F(FilterSet): """Filter for Books by Price""" price = RangeFilter() class Meta: model = Book fields = ['price'] qs = Book.objects.all().order_by('title') # Range: Books between 5€ and 15€ f = F({'price_0': '5', 'price_1': '15'}, queryset=qs) # Min-Only: Books costing more the 11€ f = F({'price_0': '11'}, queryset=qs) # Max-Only: Books costing less than 19€ f = F({'price_1': '19'}, queryset=qs)rÅ…rÆ}rÇ(hHUhIjÁubaubeubhE)rÈ}rÉ(hHUhIhohJhKhLhMhN}rÊ(hP]hQ]hR]hS]rËh)ahU]rÌhauhWKyhXhhC]rÍ(hZ)rÎ}rÏ(hHX``DateRangeFilter``rÐhIjÈhJhKhLh^hN}rÑ(hP]hQ]hR]hS]hU]uhWKyhXhhC]rÒhˆ)rÓ}rÔ(hHjÐhN}rÕ(hP]hQ]hR]hS]hU]uhIjÎhC]rÖhaXDateRangeFilterr×…rØ}rÙ(hHUhIjÓubahLhubaubhe)rÚ}rÛ(hHXsFilter similar to the admin changelist date one, it has a number of common selections for working with date fields.rÜhIjÈhJhKhLhihN}rÝ(hP]hQ]hR]hS]hU]uhWK{hXhhC]rÞhaXsFilter similar to the admin changelist date one, it has a number of common selections for working with date fields.rß…rà}rá(hHjÜhIjÚubaubeubhE)râ}rã(hHUhIhohJhKhLhMhN}rä(hP]hQ]hR]hS]råh*ahU]ræhauhWKhXhhC]rç(hZ)rè}ré(hHX``AllValuesFilter``rêhIjâhJhKhLh^hN}rë(hP]hQ]hR]hS]hU]uhWKhXhhC]rìhˆ)rí}rî(hHjêhN}rï(hP]hQ]hR]hS]hU]uhIjèhC]rðhaXAllValuesFilterrñ…rò}ró(hHUhIjíubahLhubaubhe)rô}rõ(hHXòThis is a ``ChoiceFilter`` whose choices are the current values in the database. So if in the DB for the given field you have values of 5, 7, and 9 each of those is present as an option. This is similar to the default behavior of the admin.hIjâhJhKhLhihN}rö(hP]hQ]hR]hS]hU]uhWKhXhhC]r÷(haX This is a rø…rù}rú(hHX This is a hIjôubhˆ)rû}rü(hHX``ChoiceFilter``hN}rý(hP]hQ]hR]hS]hU]uhIjôhC]rþhaX ChoiceFilterrÿ…r}r(hHUhIjûubahLhubhaXØ whose choices are the current values in the database. So if in the DB for the given field you have values of 5, 7, and 9 each of those is present as an option. This is similar to the default behavior of the admin.r…r}r(hHXØ whose choices are the current values in the database. So if in the DB for the given field you have values of 5, 7, and 9 each of those is present as an option. This is similar to the default behavior of the admin.hIjôubeubeubhE)r}r(hHUhIhohJhKhLhMhN}r(hP]hQ]hR]hS]rhBahU]r hauhWK‡hXhhC]r (hZ)r }r (hHX``MethodFilter``r hIjhJhKhLh^hN}r(hP]hQ]hR]hS]hU]uhWK‡hXhhC]rhˆ)r}r(hHj hN}r(hP]hQ]hR]hS]hU]uhIj hC]rhaX MethodFilterr…r}r(hHUhIjubahLhubaubhe)r}r(hHXÉThis is a ``Filter`` that will allow you to run a method that exists on the filter set that this filter is a property of. Set the `action` to a string that will map to a method on the filter set class.hIjhJhKhLhihN}r(hP]hQ]hR]hS]hU]uhWK‰hXhhC]r(haX This is a r…r}r(hHX This is a hIjubhˆ)r}r(hHX ``Filter``hN}r (hP]hQ]hR]hS]hU]uhIjhC]r!haXFilterr"…r#}r$(hHUhIjubahLhubhaXn that will allow you to run a method that exists on the filter set that this filter is a property of. Set the r%…r&}r'(hHXn that will allow you to run a method that exists on the filter set that this filter is a property of. Set the hIjubj2)r(}r)(hHX`action`hN}r*(hP]hQ]hR]hS]hU]uhIjhC]r+haXactionr,…r-}r.(hHUhIj(ubahLj:ubhaX? to a string that will map to a method on the filter set class.r/…r0}r1(hHX? to a string that will map to a method on the filter set class.hIjubeubeubeubhE)r2}r3(hHUhIhFhJhKhLhMhN}r4(hP]hQ]hR]hS]r5h:ahU]r6hauhWKŽhXhhC]r7(hZ)r8}r9(hHXCore Argumentsr:hIj2hJhKhLh^hN}r;(hP]hQ]hR]hS]hU]uhWKŽhXhhC]r<haXCore Argumentsr=…r>}r?(hHj:hIj8ubaubhE)r@}rA(hHUhIj2hJhKhLhMhN}rB(hP]hQ]hR]hS]rCh8ahU]rDhauhWK‘hXhhC]rE(hZ)rF}rG(hHX``name``rHhIj@hJhKhLh^hN}rI(hP]hQ]hR]hS]hU]uhWK‘hXhhC]rJhˆ)rK}rL(hHjHhN}rM(hP]hQ]hR]hS]hU]uhIjFhC]rNhaXnamerO…rP}rQ(hHUhIjKubahLhubaubhe)rR}rS(hHX”The name of the field this filter is supposed to filter on, if this is not provided it automatically becomes the filter's name on the ``FilterSet``.hIj@hJhKhLhihN}rT(hP]hQ]hR]hS]hU]uhWK“hXhhC]rU(haX†The name of the field this filter is supposed to filter on, if this is not provided it automatically becomes the filter's name on the rV…rW}rX(hHX†The name of the field this filter is supposed to filter on, if this is not provided it automatically becomes the filter's name on the hIjRubhˆ)rY}rZ(hHX ``FilterSet``hN}r[(hP]hQ]hR]hS]hU]uhIjRhC]r\haX FilterSetr]…r^}r_(hHUhIjYubahLhubhaX.…r`}ra(hHX.hIjRubeubeubhE)rb}rc(hHUhIj2hJhKhLhMhN}rd(hP]hQ]hR]hS]reh0ahU]rfh auhWK—hXhhC]rg(hZ)rh}ri(hHX ``label``rjhIjbhJhKhLh^hN}rk(hP]hQ]hR]hS]hU]uhWK—hXhhC]rlhˆ)rm}rn(hHjjhN}ro(hP]hQ]hR]hS]hU]uhIjhhC]rphaXlabelrq…rr}rs(hHUhIjmubahLhubaubhe)rt}ru(hHXSThe label as it will apear in the HTML, analogous to a form field's label argument.rvhIjbhJhKhLhihN}rw(hP]hQ]hR]hS]hU]uhWK™hXhhC]rxhaXSThe label as it will apear in the HTML, analogous to a form field's label argument.ry…rz}r{(hHjvhIjtubaubeubhE)r|}r}(hHUhIj2hJhKhLhMhN}r~(hP]hQ]hR]hS]rh2ahU]r€hauhWKhXhhC]r(hZ)r‚}rƒ(hHX ``widget``r„hIj|hJhKhLh^hN}r…(hP]hQ]hR]hS]hU]uhWKhXhhC]r†hˆ)r‡}rˆ(hHj„hN}r‰(hP]hQ]hR]hS]hU]uhIj‚hC]rŠhaXwidgetr‹…rŒ}r(hHUhIj‡ubahLhubaubhe)rŽ}r(hHX×The django.form Widget class which will represent the ``Filter``. In addition to the widgets that are included with Django that you can use there are additional ones that django-filter provides which may be useful:hIj|hJhKhLhihN}r(hP]hQ]hR]hS]hU]uhWKŸhXhhC]r‘(haX6The django.form Widget class which will represent the r’…r“}r”(hHX6The django.form Widget class which will represent the hIjŽubhˆ)r•}r–(hHX ``Filter``hN}r—(hP]hQ]hR]hS]hU]uhIjŽhC]r˜haXFilterr™…rš}r›(hHUhIj•ubahLhubhaX—. In addition to the widgets that are included with Django that you can use there are additional ones that django-filter provides which may be useful:rœ…r}rž(hHX—. In addition to the widgets that are included with Django that you can use there are additional ones that django-filter provides which may be useful:hIjŽubeubcdocutils.nodes block_quote rŸ)r }r¡(hHUhIj|hJNhLU block_quoter¢hN}r£(hP]hQ]hR]hS]hU]uhWNhXhhC]r¤cdocutils.nodes bullet_list r¥)r¦}r§(hHUhN}r¨(Ubulletr©X*hS]hR]hP]hQ]hU]uhIj hC]rªcdocutils.nodes list_item r«)r¬}r­(hHXÑ``django_filters.widgets.LinkWidget`` -- this displays the options in a mannner similar to the way the Django Admin does, as a series of links. The link for the selected option will have ``class="selected"``. hN}r®(hP]hQ]hR]hS]hU]uhIj¦hC]r¯he)r°}r±(hHXÐ``django_filters.widgets.LinkWidget`` -- this displays the options in a mannner similar to the way the Django Admin does, as a series of links. The link for the selected option will have ``class="selected"``.hIj¬hJhKhLhihN}r²(hP]hQ]hR]hS]hU]uhWK£hC]r³(hˆ)r´}rµ(hHX%``django_filters.widgets.LinkWidget``hN}r¶(hP]hQ]hR]hS]hU]uhIj°hC]r·haX!django_filters.widgets.LinkWidgetr¸…r¹}rº(hHUhIj´ubahLhubhaX– -- this displays the options in a mannner similar to the way the Django Admin does, as a series of links. The link for the selected option will have r»…r¼}r½(hHX– -- this displays the options in a mannner similar to the way the Django Admin does, as a series of links. The link for the selected option will have hIj°ubhˆ)r¾}r¿(hHX``class="selected"``hN}rÀ(hP]hQ]hR]hS]hU]uhIj°hC]rÁhaXclass="selected"rÂ…rÃ}rÄ(hHUhIj¾ubahLhubhaX.…rÅ}rÆ(hHX.hIj°ubeubahLU list_itemrÇubahLU bullet_listrÈubaubeubhE)rÉ}rÊ(hHUhIj2hJhKhLhMhN}rË(hP]hQ]hR]hS]rÌhAahU]rÍhauhWK¨hXhhC]rÎ(hZ)rÏ}rÐ(hHX ``action``rÑhIjÉhJhKhLh^hN}rÒ(hP]hQ]hR]hS]hU]uhWK¨hXhhC]rÓhˆ)rÔ}rÕ(hHjÑhN}rÖ(hP]hQ]hR]hS]hU]uhIjÏhC]r×haXactionrØ…rÙ}rÚ(hHUhIjÔubahLhubaubhe)rÛ}rÜ(hHX¾An optional callable that tells the filter how to handle the queryset. It recieves a ``QuerySet`` and the value to filter on and should return a ``Queryset`` that is filtered appropriately.hIjÉhJhKhLhihN}rÝ(hP]hQ]hR]hS]hU]uhWKªhXhhC]rÞ(haXVAn optional callable that tells the filter how to handle the queryset. It recieves a rß…rà}rá(hHXVAn optional callable that tells the filter how to handle the queryset. It recieves a hIjÛubhˆ)râ}rã(hHX ``QuerySet``hN}rä(hP]hQ]hR]hS]hU]uhIjÛhC]råhaXQuerySetræ…rç}rè(hHUhIjâubahLhubhaX0 and the value to filter on and should return a ré…rê}rë(hHX0 and the value to filter on and should return a hIjÛubhˆ)rì}rí(hHX ``Queryset``hN}rî(hP]hQ]hR]hS]hU]uhIjÛhC]rïhaXQuerysetrð…rñ}rò(hHUhIjìubahLhubhaX that is filtered appropriately.ró…rô}rõ(hHX that is filtered appropriately.hIjÛubeubeubhE)rö}r÷(hHUhIj2hJhKhLhMhN}rø(hP]hQ]hR]hS]rùh>ahU]rúhauhWK¯hXhhC]rû(hZ)rü}rý(hHX``lookup_type``rþhIjöhJhKhLh^hN}rÿ(hP]hQ]hR]hS]hU]uhWK¯hXhhC]rhˆ)r}r(hHjþhN}r(hP]hQ]hR]hS]hU]uhIjühC]rhaX lookup_typer…r}r(hHUhIjubahLhubaubhe)r}r (hHXùThe type of lookup that should be performed using the [Django ORM](https://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookups "Django's ORM Lookups"). All the normal options are allowed, and should be provided as a string. You can also provide either ``None`` or a ``list`` or a ``tuple``. If ``None`` is provided, then the user can select the lookup type from all the ones available in the Django ORM. If a ``list`` or ``tuple`` is provided, then the user can select from those options.hIjöhJhKhLhihN}r (hP]hQ]hR]hS]hU]uhWK±hXhhC]r (haXCThe type of lookup that should be performed using the [Django ORM](r …r }r(hHXCThe type of lookup that should be performed using the [Django ORM](hIjubcdocutils.nodes reference r)r}r(hHXIhttps://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookupsrhN}r(UrefurijhS]hR]hP]hQ]hU]uhIjhC]rhaXIhttps://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookupsr…r}r(hHUhIjubahLU referencerubhaX "Django's ORM Lookups"). All the normal options are allowed, and should be provided as a string. You can also provide either r…r}r(hHX "Django's ORM Lookups"). All the normal options are allowed, and should be provided as a string. You can also provide either hIjubhˆ)r}r(hHX``None``hN}r(hP]hQ]hR]hS]hU]uhIjhC]rhaXNoner …r!}r"(hHUhIjubahLhubhaX or a r#…r$}r%(hHX or a hIjubhˆ)r&}r'(hHX``list``hN}r((hP]hQ]hR]hS]hU]uhIjhC]r)haXlistr*…r+}r,(hHUhIj&ubahLhubhaX or a r-…r.}r/(hHX or a hIjubhˆ)r0}r1(hHX ``tuple``hN}r2(hP]hQ]hR]hS]hU]uhIjhC]r3haXtupler4…r5}r6(hHUhIj0ubahLhubhaX. If r7…r8}r9(hHX. If hIjubhˆ)r:}r;(hHX``None``hN}r<(hP]hQ]hR]hS]hU]uhIjhC]r=haXNoner>…r?}r@(hHUhIj:ubahLhubhaXl is provided, then the user can select the lookup type from all the ones available in the Django ORM. If a rA…rB}rC(hHXl is provided, then the user can select the lookup type from all the ones available in the Django ORM. If a hIjubhˆ)rD}rE(hHX``list``hN}rF(hP]hQ]hR]hS]hU]uhIjhC]rGhaXlistrH…rI}rJ(hHUhIjDubahLhubhaX or rK…rL}rM(hHX or hIjubhˆ)rN}rO(hHX ``tuple``hN}rP(hP]hQ]hR]hS]hU]uhIjhC]rQhaXtuplerR…rS}rT(hHUhIjNubahLhubhaX: is provided, then the user can select from those options.rU…rV}rW(hHX: is provided, then the user can select from those options.hIjubeubeubhE)rX}rY(hHUhIj2hJhKhLhMhN}rZ(hP]hQ]hR]hS]r[h/ahU]r\h auhWK¹hXhhC]r](hZ)r^}r_(hHX ``distinct``r`hIjXhJhKhLh^hN}ra(hP]hQ]hR]hS]hU]uhWK¹hXhhC]rbhˆ)rc}rd(hHj`hN}re(hP]hQ]hR]hS]hU]uhIj^hC]rfhaXdistinctrg…rh}ri(hHUhIjcubahLhubaubhe)rj}rk(hHXÏA boolean value that specifies whether the Filter will use distinct on the queryset. This option can be used to eliminate duplicate results when using filters that span related models. Defaults to ``False``.hIjXhJhKhLhihN}rl(hP]hQ]hR]hS]hU]uhWK»hXhhC]rm(haXÅA boolean value that specifies whether the Filter will use distinct on the queryset. This option can be used to eliminate duplicate results when using filters that span related models. Defaults to rn…ro}rp(hHXÅA boolean value that specifies whether the Filter will use distinct on the queryset. This option can be used to eliminate duplicate results when using filters that span related models. Defaults to hIjjubhˆ)rq}rr(hHX ``False``hN}rs(hP]hQ]hR]hS]hU]uhIjjhC]rthaXFalseru…rv}rw(hHUhIjqubahLhubhaX.…rx}ry(hHX.hIjjubeubeubhE)rz}r{(hHUhIj2hJhKhLhMhN}r|(hP]hQ]hR]hS]r}h.ahU]r~h auhWK¿hXhhC]r(hZ)r€}r(hHX ``exclude``r‚hIjzhJhKhLh^hN}rƒ(hP]hQ]hR]hS]hU]uhWK¿hXhhC]r„hˆ)r…}r†(hHj‚hN}r‡(hP]hQ]hR]hS]hU]uhIj€hC]rˆhaXexcluder‰…rŠ}r‹(hHUhIj…ubahLhubaubhe)rŒ}r(hHX~A boolean value that specifies whether the Filter should use ``filter`` or ``exclude`` on the queryset. Defaults to ``False``.hIjzhJhKhLhihN}rŽ(hP]hQ]hR]hS]hU]uhWKÁhXhhC]r(haX=A boolean value that specifies whether the Filter should use r…r‘}r’(hHX=A boolean value that specifies whether the Filter should use hIjŒubhˆ)r“}r”(hHX ``filter``hN}r•(hP]hQ]hR]hS]hU]uhIjŒhC]r–haXfilterr—…r˜}r™(hHUhIj“ubahLhubhaX or rš…r›}rœ(hHX or hIjŒubhˆ)r}rž(hHX ``exclude``hN}rŸ(hP]hQ]hR]hS]hU]uhIjŒhC]r haXexcluder¡…r¢}r£(hHUhIjubahLhubhaX on the queryset. Defaults to r¤…r¥}r¦(hHX on the queryset. Defaults to hIjŒubhˆ)r§}r¨(hHX ``False``hN}r©(hP]hQ]hR]hS]hU]uhIjŒhC]rªhaXFalser«…r¬}r­(hHUhIj§ubahLhubhaX.…r®}r¯(hHX.hIjŒubeubeubhE)r°}r±(hHUhIj2hJhKhLhMhN}r²(hP]hQ]hR]hS]r³h7ahU]r´hauhWKÆhXhhC]rµ(hZ)r¶}r·(hHX ``**kwargs``r¸hIj°hJhKhLh^hN}r¹(hP]hQ]hR]hS]hU]uhWKÆhXhhC]rºhˆ)r»}r¼(hHj¸hN}r½(hP]hQ]hR]hS]hU]uhIj¶hC]r¾haX**kwargsr¿…rÀ}rÁ(hHUhIj»ubahLhubaubhe)rÂ}rÃ(hHX”Any extra keyword arguments will be provided to the accompanying form Field. This can be used to provide arguments like ``choices`` or ``queryset``.hIj°hJhKhLhihN}rÄ(hP]hQ]hR]hS]hU]uhWKÈhXhhC]rÅ(haXxAny extra keyword arguments will be provided to the accompanying form Field. This can be used to provide arguments like rÆ…rÇ}rÈ(hHXxAny extra keyword arguments will be provided to the accompanying form Field. This can be used to provide arguments like hIjÂubhˆ)rÉ}rÊ(hHX ``choices``hN}rË(hP]hQ]hR]hS]hU]uhIjÂhC]rÌhaXchoicesrÍ…rÎ}rÏ(hHUhIjÉubahLhubhaX or rÐ…rÑ}rÒ(hHX or hIjÂubhˆ)rÓ}rÔ(hHX ``queryset``hN}rÕ(hP]hQ]hR]hS]hU]uhIjÂhC]rÖhaXquerysetr×…rØ}rÙ(hHUhIjÓubahLhubhaX.…rÚ}rÛ(hHX.hIjÂubeubeubeubeubahHUU transformerrÜNU footnote_refsrÝ}rÞUrefnamesrß}ràUsymbol_footnotesrá]râUautofootnote_refsrã]räUsymbol_footnote_refsrå]ræU citationsrç]rèhXhU current_lineréNUtransform_messagesrê]rëUreporterrìNUid_startríKU autofootnotesrî]rïU citation_refsrð}rñUindirect_targetsrò]róUsettingsrô(cdocutils.frontend Values rõorö}r÷(Ufootnote_backlinksrøKUrecord_dependenciesrùNU rfc_base_urlrúUhttp://tools.ietf.org/html/rûU tracebackrüˆUpep_referencesrýNUstrip_commentsrþNU toc_backlinksrÿUentryrU language_coderUenrU datestamprNU report_levelrKU _destinationrNU halt_levelrKU strip_classesrNh^NUerror_encoding_error_handlerrUbackslashreplacer Udebugr NUembed_stylesheetr ‰Uoutput_encoding_error_handlerr Ustrictr U sectnum_xformrKUdump_transformsrNU docinfo_xformrKUwarning_streamrNUpep_file_url_templaterUpep-%04drUexit_status_levelrKUconfigrNUstrict_visitorrNUcloak_email_addressesrˆUtrim_footnote_reference_spacer‰UenvrNUdump_pseudo_xmlrNUexpose_internalsrNUsectsubtitle_xformr‰U source_linkrNUrfc_referencesrNUoutput_encodingrUutf-8r U source_urlr!NUinput_encodingr"U utf-8-sigr#U_disable_configr$NU id_prefixr%UU tab_widthr&KUerror_encodingr'UUTF-8r(U_sourcer)hKUgettext_compactr*ˆU generatorr+NUdump_internalsr,NU smart_quotesr-‰U pep_base_urlr.Uhttp://www.python.org/dev/peps/r/Usyntax_highlightr0Ulongr1Uinput_encoding_error_handlerr2j Uauto_id_prefixr3Uidr4Udoctitle_xformr5‰Ustrip_elements_with_classesr6NU _config_filesr7]Ufile_insertion_enabledr8ˆU raw_enabledr9KU dump_settingsr:NubUsymbol_footnote_startr;KUidsr<}r=(h)jÈh*jâh+jph,jÎh-hoh>jöh.jzh/jXh0jbh7j°h:j2h2j|h3jòh4j§h5jh6híh8j@h9jh;jCh1hFh}r?hLhXhN}r@(hP]hS]hR]UsourcehKhQ]hU]uU footnotesrA]rBUrefidsrC}rDub.django-filter-0.11.0/docs/_build/doctrees/ref/widgets.doctree0000644000076500000240000001463012436054334024702 0ustar carltonstaff00000000000000€cdocutils.nodes document q)q}q(U nametypesq}q(Xwidget referenceqNX linkwidgetqNuUsubstitution_defsq}q Uparse_messagesq ]q cdocutils.nodes system_message q )q }q(U rawsourceqUUparentqcdocutils.nodes section q)q}q(hUhh)q}q(hUhhUsourceqXH/Users/carlton/Documents/Django-Stack/django-filter/docs/ref/widgets.txtqUtagnameqUsectionqU attributesq}q(Udupnamesq]Uclassesq]Ubackrefsq]Uidsq]q Uwidget-referenceq!aUnamesq"]q#hauUlineq$KUdocumentq%hUchildrenq&]q'(cdocutils.nodes title q()q)}q*(hXWidget Referenceq+hhhhhUtitleq,h}q-(h]h]h]h]h"]uh$Kh%hh&]q.cdocutils.nodes Text q/XWidget Referenceq0…q1}q2(hh+hh)ubaubcdocutils.nodes paragraph q3)q4}q5(hXUThis is a reference document with a list of the provided widgets and their arguments.q6hhhhhU paragraphq7h}q8(h]h]h]h]h"]uh$Kh%hh&]q9h/XUThis is a reference document with a list of the provided widgets and their arguments.q:…q;}q<(hh6hh4ubaubheubhhhhh}q=(h]h]h]h]q>U linkwidgetq?ah"]q@hauh$Kh%hh&]qA(h()qB}qC(hX``LinkWidget``qDhhhhhh,h}qE(h]h]h]h]h"]uh$Kh%hh&]qFcdocutils.nodes literal qG)qH}qI(hhDh}qJ(h]h]h]h]h"]uhhBh&]qKh/X LinkWidgetqL…qM}qN(hUhhHubahUliteralqOubaubh3)qP}qQ(hXéThis widget renders each option as a link, instead of an actual . It has one method that you can overide for additional customizability. ``option_string()`` should return a string with 3 Python keyword argument placeholders::hhhhhh7h}qR(h]h]h]h]h"]uh$K h%hh&]qS(h/X‘This widget renders each option as a link, instead of an actual . It has one method that you can overide for additional customizability. qT…qU}qV(hX‘This widget renders each option as a link, instead of an actual . It has one method that you can overide for additional customizability. hhPubhG)qW}qX(hX``option_string()``h}qY(h]h]h]h]h"]uhhPh&]qZh/Xoption_string()q[…q\}q](hUhhWubahhOubh/XD should return a string with 3 Python keyword argument placeholders:q^…q_}q`(hXD should return a string with 3 Python keyword argument placeholders:hhPubeubcdocutils.nodes enumerated_list qa)qb}qc(hUhhhhhUenumerated_listqdh}qe(UsuffixqfU.h]h]h]UprefixqgUh]h"]UenumtypeqhUarabicqiuh$Kh%hh&]qj(cdocutils.nodes list_item qk)ql}qm(hXZ``attrs``: This is a string with all the attributes that will be on the final ```` tag.hhbhhhU list_itemqnh}qo(h]h]h]h]h"]uh$Nh%hh&]qph3)qq}qr(hXZ``attrs``: This is a string with all the attributes that will be on the final ```` tag.hhlhhhh7h}qs(h]h]h]h]h"]uh$Kh&]qt(hG)qu}qv(hX ``attrs``h}qw(h]h]h]h]h"]uhhqh&]qxh/Xattrsqy…qz}q{(hUhhuubahhOubh/XE: This is a string with all the attributes that will be on the final q|…q}}q~(hXE: This is a string with all the attributes that will be on the final hhqubhG)q}q€(hX````h}q(h]h]h]h]h"]uhhqh&]q‚h/Xqƒ…q„}q…(hUhhubahhOubh/X tag.q†…q‡}qˆ(hX tag.hhqubeubaubhk)q‰}qŠ(hXb``query_string``: This is the query string for use in the ``href`` option on the ```` elemeent.hhbhhhhnh}q‹(h]h]h]h]h"]uh$Nh%hh&]qŒh3)q}qŽ(hXb``query_string``: This is the query string for use in the ``href`` option on the ```` elemeent.hh‰hhhh7h}q(h]h]h]h]h"]uh$Kh&]q(hG)q‘}q’(hX``query_string``h}q“(h]h]h]h]h"]uhhh&]q”h/X query_stringq•…q–}q—(hUhh‘ubahhOubh/X*: This is the query string for use in the q˜…q™}qš(hX*: This is the query string for use in the hhubhG)q›}qœ(hX``href``h}q(h]h]h]h]h"]uhhh&]qžh/XhrefqŸ…q }q¡(hUhh›ubahhOubh/X option on the q¢…q£}q¤(hX option on the hhubhG)q¥}q¦(hX````h}q§(h]h]h]h]h"]uhhh&]q¨h/Xq©…qª}q«(hUhh¥ubahhOubh/X elemeent.q¬…q­}q®(hX elemeent.hhubeubaubhk)q¯}q°(hX8``label``: This is the text to be displayed to the user.q±hhbhhhhnh}q²(h]h]h]h]h"]uh$Nh%hh&]q³h3)q´}qµ(hh±hh¯hhhh7h}q¶(h]h]h]h]h"]uh$Kh&]q·(hG)q¸}q¹(hX ``label``h}qº(h]h]h]h]h"]uhh´h&]q»h/Xlabelq¼…q½}q¾(hUhh¸ubahhOubh/X/: This is the text to be displayed to the user.q¿…qÀ}qÁ(hX/: This is the text to be displayed to the user.hh´ubeubaubeubeubhhhUsystem_messageqÂh}qÃ(h]UlevelKh]h]Usourcehh]h"]UlineKUtypeUWARNINGqÄuh$Kh%hh&]qÅh3)qÆ}qÇ(hUh}qÈ(h]h]h]h]h"]uhh h&]qÉh/X#Literal block expected; none found.qÊ…qË}qÌ(hUhhÆubahh7ubaubaUcurrent_sourceqÍNU decorationqÎNUautofootnote_startqÏKUnameidsqÐ}qÑ(hh!hh?uh&]qÒhahUU transformerqÓNU footnote_refsqÔ}qÕUrefnamesqÖ}q×Usymbol_footnotesqØ]qÙUautofootnote_refsqÚ]qÛUsymbol_footnote_refsqÜ]qÝU citationsqÞ]qßh%hU current_lineqàNUtransform_messagesqá]qâUreporterqãNUid_startqäKU autofootnotesqå]qæU citation_refsqç}qèUindirect_targetsqé]qêUsettingsqë(cdocutils.frontend Values qìoqí}qî(Ufootnote_backlinksqïKUrecord_dependenciesqðNU rfc_base_urlqñUhttp://tools.ietf.org/html/qòU tracebackqóˆUpep_referencesqôNUstrip_commentsqõNU toc_backlinksqöUentryq÷U language_codeqøUenqùU datestampqúNU report_levelqûKU _destinationqüNU halt_levelqýKU strip_classesqþNh,NUerror_encoding_error_handlerqÿUbackslashreplacerUdebugrNUembed_stylesheetr‰Uoutput_encoding_error_handlerrUstrictrU sectnum_xformrKUdump_transformsrNU docinfo_xformrKUwarning_streamrNUpep_file_url_templater Upep-%04dr Uexit_status_levelr KUconfigr NUstrict_visitorr NUcloak_email_addressesrˆUtrim_footnote_reference_spacer‰UenvrNUdump_pseudo_xmlrNUexpose_internalsrNUsectsubtitle_xformr‰U source_linkrNUrfc_referencesrNUoutput_encodingrUutf-8rU source_urlrNUinput_encodingrU utf-8-sigrU_disable_configrNU id_prefixrUU tab_widthrKUerror_encodingrUUTF-8rU_sourcer hUgettext_compactr!ˆU generatorr"NUdump_internalsr#NU smart_quotesr$‰U pep_base_urlr%Uhttp://www.python.org/dev/peps/r&Usyntax_highlightr'Ulongr(Uinput_encoding_error_handlerr)jUauto_id_prefixr*Uidr+Udoctitle_xformr,‰Ustrip_elements_with_classesr-NU _config_filesr.]r/Ufile_insertion_enabledr0ˆU raw_enabledr1KU dump_settingsr2NubUsymbol_footnote_startr3KUidsr4}r5(h!hh?huUsubstitution_namesr6}r7hh%h}r8(h]h]h]Usourcehh]h"]uU footnotesr9]r:Urefidsr;}r<ub.django-filter-0.11.0/docs/_build/doctrees/tests.doctree0000644000076500000240000001677112436054334023632 0ustar carltonstaff00000000000000€cdocutils.nodes document q)q}q(U nametypesq}q(Xrunning the django-filter testsqNXget a copy of django-filterqNXinstall the test dependenciesqNX&set up a virtualenv for the test suiteq NuUsubstitution_defsq }q Uparse_messagesq ]q Ucurrent_sourceqNU decorationqNUautofootnote_startqKUnameidsq}q(hUrunning-the-django-filter-testsqhUget-a-copy-of-django-filterqhUinstall-the-test-dependenciesqh U&set-up-a-virtualenv-for-the-test-suitequUchildrenq]qcdocutils.nodes section q)q}q(U rawsourceqUUparentqhUsourceqXB/Users/carlton/Documents/Django-Stack/django-filter/docs/tests.txtqUtagnameq Usectionq!U attributesq"}q#(Udupnamesq$]Uclassesq%]Ubackrefsq&]Uidsq']q(haUnamesq)]q*hauUlineq+KUdocumentq,hh]q-(cdocutils.nodes title q.)q/}q0(hXRunning the django-filter testsq1hhhhh Utitleq2h"}q3(h$]h%]h&]h']h)]uh+Kh,hh]q4cdocutils.nodes Text q5XRunning the django-filter testsq6…q7}q8(hh1hh/ubaubcdocutils.nodes paragraph q9)q:}q;(hXThe easiest way to run the django-filter tests is to check out the source code into a virtualenv, where you can install the test dependencies. django-filter uses a custom test runner to locate all of the tests, so a wrapper script is available to set up and run the test suite.q(h$]h%]h&]h']h)]uh+Kh,hh]q?h5XThe easiest way to run the django-filter tests is to check out the source code into a virtualenv, where you can install the test dependencies. django-filter uses a custom test runner to locate all of the tests, so a wrapper script is available to set up and run the test suite.q@…qA}qB(hhGet the django-filter source code using the following command:q­…q®}q¯(hX>Get the django-filter source code using the following command:hh¨ubaubh)q°}q±(hX3git clone https://github.com/alex/django-filter.githhšhhh h’h"}q²(h”h•h']h&]h$]h%]h)]uh+Kh,hh]q³h5X3git clone https://github.com/alex/django-filter.gitq´…qµ}q¶(hUhh°ubaubh9)q·}q¸(hX'Switch to the django-filter directory::q¹hhšhhh h=h"}qº(h$]h%]h&]h']h)]uh+K h,hh]q»h5X&Switch to the django-filter directory:q¼…q½}q¾(hX&Switch to the django-filter directory:hh·ubaubh)q¿}qÀ(hXcd django-filterhhšhhh h’h"}qÁ(h”h•h']h&]h$]h%]h)]uh+K"h,hh]qÂh5Xcd django-filterqÃ…qÄ}qÅ(hUhh¿ubaubeubh)qÆ}qÇ(hUhhhhh h!h"}qÈ(h$]h%]h&]h']qÉhah)]qÊhauh+K%h,hh]qË(h.)qÌ}qÍ(hXInstall the test dependenciesqÎhhÆhhh h2h"}qÏ(h$]h%]h&]h']h)]uh+K%h,hh]qÐh5XInstall the test dependenciesqÑ…qÒ}qÓ(hhÎhhÌubaubh9)qÔ}qÕ(hXJRun the following to install the test dependencies within the virutalenv::hhÆhhh h=h"}qÖ(h$]h%]h&]h']h)]uh+K'h,hh]q×h5XIRun the following to install the test dependencies within the virutalenv:qØ…qÙ}qÚ(hXIRun the following to install the test dependencies within the virutalenv:hhÔubaubh)qÛ}qÜ(hX$pip install -r requirements/test.txthhÆhhh h’h"}qÝ(h”h•h']h&]h$]h%]h)]uh+K*h,hh]qÞh5X$pip install -r requirements/test.txtqß…qà}qá(hUhhÛubaubh9)qâ}qã(hXRun the django-filter tests::qähhÆhhh h=h"}qå(h$]h%]h&]h']h)]uh+K,h,hh]qæh5XRun the django-filter tests:qç…qè}qé(hXRun the django-filter tests:hhâubaubh)qê}që(hXpython runtests.pyhhÆhhh h’h"}qì(h”h•h']h&]h$]h%]h)]uh+K.h,hh]qíh5Xpython runtests.pyqî…qï}qð(hUhhêubaubeubeubahUU transformerqñNU footnote_refsqò}qóUrefnamesqô}qõUsymbol_footnotesqö]q÷Uautofootnote_refsqø]qùUsymbol_footnote_refsqú]qûU citationsqü]qýh,hU current_lineqþNUtransform_messagesqÿ]rUreporterrNUid_startrKU autofootnotesr]rU citation_refsr}rUindirect_targetsr]rUsettingsr (cdocutils.frontend Values r or }r (Ufootnote_backlinksr KUrecord_dependenciesrNU rfc_base_urlrUhttp://tools.ietf.org/html/rU tracebackrˆUpep_referencesrNUstrip_commentsrNU toc_backlinksrUentryrU language_coderUenrU datestamprNU report_levelrKU _destinationrNU halt_levelrKU strip_classesrNh2NUerror_encoding_error_handlerrUbackslashreplacerUdebugrNUembed_stylesheetr ‰Uoutput_encoding_error_handlerr!Ustrictr"U sectnum_xformr#KUdump_transformsr$NU docinfo_xformr%KUwarning_streamr&NUpep_file_url_templater'Upep-%04dr(Uexit_status_levelr)KUconfigr*NUstrict_visitorr+NUcloak_email_addressesr,ˆUtrim_footnote_reference_spacer-‰Uenvr.NUdump_pseudo_xmlr/NUexpose_internalsr0NUsectsubtitle_xformr1‰U source_linkr2NUrfc_referencesr3NUoutput_encodingr4Uutf-8r5U source_urlr6NUinput_encodingr7U utf-8-sigr8U_disable_configr9NU id_prefixr:UU tab_widthr;KUerror_encodingr<UUTF-8r=U_sourcer>hUgettext_compactr?ˆU generatorr@NUdump_internalsrANU smart_quotesrB‰U pep_base_urlrCUhttp://www.python.org/dev/peps/rDUsyntax_highlightrEUlongrFUinput_encoding_error_handlerrGj"Uauto_id_prefixrHUidrIUdoctitle_xformrJ‰Ustrip_elements_with_classesrKNU _config_filesrL]Ufile_insertion_enabledrMˆU raw_enabledrNKU dump_settingsrONubUsymbol_footnote_startrPKUidsrQ}rR(hhšhhhxhthshmhhÆhhyuUsubstitution_namesrS}rTh h,h"}rU(h$]h']h&]Usourcehh%]h)]uU footnotesrV]rWUrefidsrX}rYub.django-filter-0.11.0/docs/_build/doctrees/usage.doctree0000644000076500000240000012072412436054334023566 0ustar carltonstaff00000000000000€cdocutils.nodes document q)q}q(U nametypesq}q(Xcustom forms using formqNX the filterqNXnon-meta optionsqNX django's ormq ˆXusing django-filterq NXstrictq NXoverriding filterset methodsq NX the url confq NX the templateqNXget_ordering_field()qNXordering using order_byqNX generic viewqNX the modelqNXthe viewqNXother meta optionsqNuUsubstitution_defsq}qUparse_messagesq]qUcurrent_sourceqNU decorationqNUautofootnote_startqKUnameidsq}q(hUcustom-forms-using-formqhU the-filterqhUnon-meta-optionsq h U django-s-ormq!h Uusing-django-filterq"h Ustrictq#h Uoverriding-filterset-methodsq$h U the-url-confq%hU the-templateq&hUget-ordering-fieldq'hUordering-using-order-byq(hU generic-viewq)hU the-modelq*hUthe-viewq+hUother-meta-optionsq,uUchildrenq-]q.cdocutils.nodes section q/)q0}q1(U rawsourceq2UUparentq3hUsourceq4XB/Users/carlton/Documents/Django-Stack/django-filter/docs/usage.txtq5Utagnameq6Usectionq7U attributesq8}q9(Udupnamesq:]Uclassesq;]Ubackrefsq<]Uidsq=]q>h"aUnamesq?]q@h auUlineqAKUdocumentqBhh-]qC(cdocutils.nodes title qD)qE}qF(h2XUsing django-filterqGh3h0h4h5h6UtitleqHh8}qI(h:]h;]h<]h=]h?]uhAKhBhh-]qJcdocutils.nodes Text qKXUsing django-filterqL…qM}qN(h2hGh3hEubaubcdocutils.nodes paragraph qO)qP}qQ(h2XÏDjango-filter provides a simple way to filter down a queryset based on parameters a user provides. Say we have a ``Product`` model and we want to let our users filter which products they see on a list page.h3h0h4h5h6U paragraphqRh8}qS(h:]h;]h<]h=]h?]uhAKhBhh-]qT(hKXrDjango-filter provides a simple way to filter down a queryset based on parameters a user provides. Say we have a qU…qV}qW(h2XrDjango-filter provides a simple way to filter down a queryset based on parameters a user provides. Say we have a h3hPubcdocutils.nodes literal qX)qY}qZ(h2X ``Product``h8}q[(h:]h;]h<]h=]h?]uh3hPh-]q\hKXProductq]…q^}q_(h2Uh3hYubah6Uliteralq`ubhKXR model and we want to let our users filter which products they see on a list page.qa…qb}qc(h2XR model and we want to let our users filter which products they see on a list page.h3hPubeubh/)qd}qe(h2Uh3h0h4h5h6h7h8}qf(h:]h;]h<]h=]qgh*ah?]qhhauhAK hBhh-]qi(hD)qj}qk(h2X The modelqlh3hdh4h5h6hHh8}qm(h:]h;]h<]h=]h?]uhAK hBhh-]qnhKX The modelqo…qp}qq(h2hlh3hjubaubhO)qr}qs(h2XLet's start with our model::qth3hdh4h5h6hRh8}qu(h:]h;]h<]h=]h?]uhAK hBhh-]qvhKXLet's start with our model:qw…qx}qy(h2XLet's start with our model:h3hrubaubcdocutils.nodes literal_block qz)q{}q|(h2Xfrom django.db import models class Product(models.Model): name = models.CharField(max_length=255) price = models.DecimalField() description = models.TextField() release_date = models.DateField() manufacturer = models.ForeignKey(Manufacturer)h3hdh4h5h6U literal_blockq}h8}q~(U xml:spaceqUpreserveq€h=]h<]h:]h;]h?]uhAK hBhh-]qhKXfrom django.db import models class Product(models.Model): name = models.CharField(max_length=255) price = models.DecimalField() description = models.TextField() release_date = models.DateField() manufacturer = models.ForeignKey(Manufacturer)q‚…qƒ}q„(h2Uh3h{ubaubeubh/)q…}q†(h2Uh3h0h4h5h6h7h8}q‡(h:]h;]h<]h=]qˆhah?]q‰hauhAKhBhh-]qŠ(hD)q‹}qŒ(h2X The filterqh3h…h4h5h6hHh8}qŽ(h:]h;]h<]h=]h?]uhAKhBhh-]qhKX The filterq…q‘}q’(h2hh3h‹ubaubhO)q“}q”(h2XŒWe have a number of fields and we want to let our users filter based on the price or the release_date. We create a ``FilterSet`` for this::h3h…h4h5h6hRh8}q•(h:]h;]h<]h=]h?]uhAKhBhh-]q–(hKXtWe have a number of fields and we want to let our users filter based on the price or the release_date. We create a q—…q˜}q™(h2XtWe have a number of fields and we want to let our users filter based on the price or the release_date. We create a h3h“ubhX)qš}q›(h2X ``FilterSet``h8}qœ(h:]h;]h<]h=]h?]uh3h“h-]qhKX FilterSetqž…qŸ}q (h2Uh3hšubah6h`ubhKX for this:q¡…q¢}q£(h2X for this:h3h“ubeubhz)q¤}q¥(h2X˜import django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['price', 'release_date']h3h…h4h5h6h}h8}q¦(hh€h=]h<]h:]h;]h?]uhAKhBhh-]q§hKX˜import django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['price', 'release_date']q¨…q©}qª(h2Uh3h¤ubaubhO)q«}q¬(h2X±As you can see this uses a very similar API to Django's ``ModelForm``. Just like with a ``ModelForm`` we can also override filters, or add new ones using a declarative syntax::h3h…h4h5h6hRh8}q­(h:]h;]h<]h=]h?]uhAK$hBhh-]q®(hKX8As you can see this uses a very similar API to Django's q¯…q°}q±(h2X8As you can see this uses a very similar API to Django's h3h«ubhX)q²}q³(h2X ``ModelForm``h8}q´(h:]h;]h<]h=]h?]uh3h«h-]qµhKX ModelFormq¶…q·}q¸(h2Uh3h²ubah6h`ubhKX. Just like with a q¹…qº}q»(h2X. Just like with a h3h«ubhX)q¼}q½(h2X ``ModelForm``h8}q¾(h:]h;]h<]h=]h?]uh3h«h-]q¿hKX ModelFormqÀ…qÁ}qÂ(h2Uh3h¼ubah6h`ubhKXJ we can also override filters, or add new ones using a declarative syntax:qÃ…qÄ}qÅ(h2XJ we can also override filters, or add new ones using a declarative syntax:h3h«ubeubhz)qÆ}qÇ(h2XÒimport django_filters class ProductFilter(django_filters.FilterSet): price = django_filters.NumberFilter(lookup_type='lt') class Meta: model = Product fields = ['price', 'release_date']h3h…h4h5h6h}h8}qÈ(hh€h=]h<]h:]h;]h?]uhAK(hBhh-]qÉhKXÒimport django_filters class ProductFilter(django_filters.FilterSet): price = django_filters.NumberFilter(lookup_type='lt') class Meta: model = Product fields = ['price', 'release_date']qÊ…qË}qÌ(h2Uh3hÆubaubhO)qÍ}qÎ(h2XÂFilters take a ``lookup_type`` argument which specifies what lookup type to use with `Django's ORM`_. So here when a user entered a price it would show all Products with a price less than that.h3h…h4h5h6hRh8}qÏ(h:]h;]h<]h=]h?]uhAK0hBhh-]qÐ(hKXFilters take a qÑ…qÒ}qÓ(h2XFilters take a h3hÍubhX)qÔ}qÕ(h2X``lookup_type``h8}qÖ(h:]h;]h<]h=]h?]uh3hÍh-]q×hKX lookup_typeqØ…qÙ}qÚ(h2Uh3hÔubah6h`ubhKX7 argument which specifies what lookup type to use with qÛ…qÜ}qÝ(h2X7 argument which specifies what lookup type to use with h3hÍubcdocutils.nodes reference qÞ)qß}qà(h2X`Django's ORM`_UresolvedqáKh3hÍh6U referenceqâh8}qã(UnameX Django's ORMUrefuriqäXIhttps://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookupsqåh=]h<]h:]h;]h?]uh-]qæhKX Django's ORMqç…qè}qé(h2Uh3hßubaubhKX^. So here when a user entered a price it would show all Products with a price less than that.qê…që}qì(h2X^. So here when a user entered a price it would show all Products with a price less than that.h3hÍubeubcdocutils.nodes target qí)qî}qï(h2X].. _`Django's ORM`: https://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookupsU referencedqðKh3h…h4h5h6Utargetqñh8}qò(hähåh=]qóh!ah<]h:]h;]h?]qôh auhAK4hBhh-]ubhO)qõ}qö(h2Xô**It's quite common to forget to set lookup type for `CharField`s/`TextField`s and wonder why search for "foo" doesn't return result for "foobar". It's because default lookup type is exact text, but you probably want `icontains` lookup field.**q÷h3h…h4h5h6hRh8}qø(h:]h;]h<]h=]h?]uhAK6hBhh-]qùcdocutils.nodes strong qú)qû}qü(h2h÷h8}qý(h:]h;]h<]h=]h?]uh3hõh-]qþhKXðIt's quite common to forget to set lookup type for `CharField`s/`TextField`s and wonder why search for "foo" doesn't return result for "foobar". It's because default lookup type is exact text, but you probably want `icontains` lookup field.qÿ…r}r(h2Uh3hûubah6UstrongrubaubhO)r}r(h2XThe FilterSet Meta class fields can additionally be set using a Dictionary to specify multiple ``lookup_type`` filters without significant code duplication::h3h…h4h5h6hRh8}r(h:]h;]h<]h=]h?]uhAK;hBhh-]r(hKX_The FilterSet Meta class fields can additionally be set using a Dictionary to specify multiple r…r}r (h2X_The FilterSet Meta class fields can additionally be set using a Dictionary to specify multiple h3jubhX)r }r (h2X``lookup_type``h8}r (h:]h;]h<]h=]h?]uh3jh-]r hKX lookup_typer…r}r(h2Uh3j ubah6h`ubhKX. filters without significant code duplication:r…r}r(h2X. filters without significant code duplication:h3jubeubhz)r}r(h2XÖimport django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = {'price': ['lt', 'gt'], 'release_date': ['exact'], }h3h…h4h5h6h}h8}r(hh€h=]h<]h:]h;]h?]uhAK>hBhh-]rhKXÖimport django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = {'price': ['lt', 'gt'], 'release_date': ['exact'], }r…r}r(h2Uh3jubaubhO)r}r(h2X¯The above would generate 'price__lt', 'price__gt' and 'release_date' filters. The filter lookup type keyword 'exact' is the default and therefore never added to a filter name.rh3h…h4h5h6hRh8}r(h:]h;]h<]h=]h?]uhAKGhBhh-]rhKX¯The above would generate 'price__lt', 'price__gt' and 'release_date' filters. The filter lookup type keyword 'exact' is the default and therefore never added to a filter name.r …r!}r"(h2jh3jubaubhO)r#}r$(h2XItems in the ``fields`` sequence in the ``Meta`` class may include "relationship paths" using Django's ``__`` syntax to filter on fields on a related model::h3h…h4h5h6hRh8}r%(h:]h;]h<]h=]h?]uhAKKhBhh-]r&(hKX Items in the r'…r(}r)(h2X Items in the h3j#ubhX)r*}r+(h2X ``fields``h8}r,(h:]h;]h<]h=]h?]uh3j#h-]r-hKXfieldsr.…r/}r0(h2Uh3j*ubah6h`ubhKX sequence in the r1…r2}r3(h2X sequence in the h3j#ubhX)r4}r5(h2X``Meta``h8}r6(h:]h;]h<]h=]h?]uh3j#h-]r7hKXMetar8…r9}r:(h2Uh3j4ubah6h`ubhKX7 class may include "relationship paths" using Django's r;…r<}r=(h2X7 class may include "relationship paths" using Django's h3j#ubhX)r>}r?(h2X``__``h8}r@(h:]h;]h<]h=]h?]uh3j#h-]rAhKX__rB…rC}rD(h2Uh3j>ubah6h`ubhKX/ syntax to filter on fields on a related model:rE…rF}rG(h2X/ syntax to filter on fields on a related model:h3j#ubeubhz)rH}rI(h2Xclass ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['manufacturer__country']h3h…h4h5h6h}h8}rJ(hh€h=]h<]h:]h;]h?]uhAKOhBhh-]rKhKXclass ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['manufacturer__country']rL…rM}rN(h2Uh3jHubaubhO)rO}rP(h2XFilters also take any arbitrary keyword arguments which get passed onto the ``django.forms.Field`` initializer. These extra keyword arguments get stored in ``Filter.extra``, so it's possible to override the initializer of a ``FilterSet`` to add extra ones::h3h…h4h5h6hRh8}rQ(h:]h;]h<]h=]h?]uhAKThBhh-]rR(hKXLFilters also take any arbitrary keyword arguments which get passed onto the rS…rT}rU(h2XLFilters also take any arbitrary keyword arguments which get passed onto the h3jOubhX)rV}rW(h2X``django.forms.Field``h8}rX(h:]h;]h<]h=]h?]uh3jOh-]rYhKXdjango.forms.FieldrZ…r[}r\(h2Uh3jVubah6h`ubhKX; initializer. These extra keyword arguments get stored in r]…r^}r_(h2X; initializer. These extra keyword arguments get stored in h3jOubhX)r`}ra(h2X``Filter.extra``h8}rb(h:]h;]h<]h=]h?]uh3jOh-]rchKX Filter.extrard…re}rf(h2Uh3j`ubah6h`ubhKX4, so it's possible to override the initializer of a rg…rh}ri(h2X4, so it's possible to override the initializer of a h3jOubhX)rj}rk(h2X ``FilterSet``h8}rl(h:]h;]h<]h=]h?]uh3jOh-]rmhKX FilterSetrn…ro}rp(h2Uh3jjubah6h`ubhKX to add extra ones:rq…rr}rs(h2X to add extra ones:h3jOubeubhz)rt}ru(h2XDclass ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['manufacturer'] def __init__(self, *args, **kwargs): super(ProductFilter, self).__init__(*args, **kwargs) self.filters['manufacturer'].extra.update( {'empty_label': 'All Manufacturers'})h3h…h4h5h6h}h8}rv(hh€h=]h<]h:]h;]h?]uhAKYhBhh-]rwhKXDclass ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['manufacturer'] def __init__(self, *args, **kwargs): super(ProductFilter, self).__init__(*args, **kwargs) self.filters['manufacturer'].extra.update( {'empty_label': 'All Manufacturers'})rx…ry}rz(h2Uh3jtubaubhO)r{}r|(h2XœLike ``django.contrib.admin.ModelAdmin``, it is possible to override default filters for all the models fields of the same kind using ``filter_overrides``::h3h…h4h5h6hRh8}r}(h:]h;]h<]h=]h?]uhAKchBhh-]r~(hKXLike r…r€}r(h2XLike h3j{ubhX)r‚}rƒ(h2X#``django.contrib.admin.ModelAdmin``h8}r„(h:]h;]h<]h=]h?]uh3j{h-]r…hKXdjango.contrib.admin.ModelAdminr†…r‡}rˆ(h2Uh3j‚ubah6h`ubhKX^, it is possible to override default filters for all the models fields of the same kind using r‰…rŠ}r‹(h2X^, it is possible to override default filters for all the models fields of the same kind using h3j{ubhX)rŒ}r(h2X``filter_overrides``h8}rŽ(h:]h;]h<]h=]h?]uh3j{h-]rhKXfilter_overridesr…r‘}r’(h2Uh3jŒubah6h`ubhKX:…r“}r”(h2X:h3j{ubeubhz)r•}r–(h2XHclass ProductFilter(django_filters.FilterSet): filter_overrides = { models.CharField: { 'filter_class': django_filters.CharFilter, 'extra': lambda f: { 'lookup_type': 'icontains', } } } class Meta: model = Product fields = ['name']h3h…h4h5h6h}h8}r—(hh€h=]h<]h:]h;]h?]uhAKghBhh-]r˜hKXHclass ProductFilter(django_filters.FilterSet): filter_overrides = { models.CharField: { 'filter_class': django_filters.CharFilter, 'extra': lambda f: { 'lookup_type': 'icontains', } } } class Meta: model = Product fields = ['name']r™…rš}r›(h2Uh3j•ubaubeubh/)rœ}r(h2Uh3h0h4h5h6h7h8}rž(h:]h;]h<]h=]rŸh+ah?]r hauhAKwhBhh-]r¡(hD)r¢}r£(h2XThe viewr¤h3jœh4h5h6hHh8}r¥(h:]h;]h<]h=]h?]uhAKwhBhh-]r¦hKXThe viewr§…r¨}r©(h2j¤h3j¢ubaubhO)rª}r«(h2XNow we need to write a view::r¬h3jœh4h5h6hRh8}r­(h:]h;]h<]h=]h?]uhAKyhBhh-]r®hKXNow we need to write a view:r¯…r°}r±(h2XNow we need to write a view:h3jªubaubhz)r²}r³(h2X¢def product_list(request): f = ProductFilter(request.GET, queryset=Product.objects.all()) return render_to_response('my_app/template.html', {'filter': f})h3jœh4h5h6h}h8}r´(hh€h=]h<]h:]h;]h?]uhAK{hBhh-]rµhKX¢def product_list(request): f = ProductFilter(request.GET, queryset=Product.objects.all()) return render_to_response('my_app/template.html', {'filter': f})r¶…r·}r¸(h2Uh3j²ubaubhO)r¹}rº(h2XjIf a queryset argument isn't provided then all the items in the default manager of the model will be used.r»h3jœh4h5h6hRh8}r¼(h:]h;]h<]h=]h?]uhAKhBhh-]r½hKXjIf a queryset argument isn't provided then all the items in the default manager of the model will be used.r¾…r¿}rÀ(h2j»h3j¹ubaubhO)rÁ}rÂ(h2X…If you want to access the filtered objects in your views, for example if you want to paginate them, you can do that. They are in f.qsrÃh3jœh4h5h6hRh8}rÄ(h:]h;]h<]h=]h?]uhAK‚hBhh-]rÅhKX…If you want to access the filtered objects in your views, for example if you want to paginate them, you can do that. They are in f.qsrÆ…rÇ}rÈ(h2jÃh3jÁubaubeubh/)rÉ}rÊ(h2Uh3h0h4h5h6h7h8}rË(h:]h;]h<]h=]rÌh%ah?]rÍh auhAK†hBhh-]rÎ(hD)rÏ}rÐ(h2X The URL confrÑh3jÉh4h5h6hHh8}rÒ(h:]h;]h<]h=]h?]uhAK†hBhh-]rÓhKX The URL confrÔ…rÕ}rÖ(h2jÑh3jÏubaubhO)r×}rØ(h2X(We need a URL pattern to call the view::rÙh3jÉh4h5h6hRh8}rÚ(h:]h;]h<]h=]h?]uhAKˆhBhh-]rÛhKX'We need a URL pattern to call the view:rÜ…rÝ}rÞ(h2X'We need a URL pattern to call the view:h3j×ubaubhz)rß}rà(h2X"url(r'^list$', views.product_list)h3jÉh4h5h6h}h8}rá(hh€h=]h<]h:]h;]h?]uhAKŠhBhh-]râhKX"url(r'^list$', views.product_list)rã…rä}rå(h2Uh3jßubaubeubh/)ræ}rç(h2Uh3h0h4h5h6h7h8}rè(h:]h;]h<]h=]réh&ah?]rêhauhAKhBhh-]rë(hD)rì}rí(h2X The templaterîh3jæh4h5h6hHh8}rï(h:]h;]h<]h=]h?]uhAKhBhh-]rðhKX The templaterñ…rò}ró(h2jîh3jìubaubhO)rô}rõ(h2XAnd lastly we need a template::röh3jæh4h5h6hRh8}r÷(h:]h;]h<]h=]h?]uhAKhBhh-]røhKXAnd lastly we need a template:rù…rú}rû(h2XAnd lastly we need a template:h3jôubaubhz)rü}rý(h2X{% extends "base.html" %} {% block content %}
    {{ filter.form.as_p }}
    {% for obj in filter %} {{ obj.name }} - ${{ obj.price }}
    {% endfor %} {% endblock %}h3jæh4h5h6h}h8}rþ(hh€h=]h<]h:]h;]h?]uhAK‘hBhh-]rÿhKX{% extends "base.html" %} {% block content %}
    {{ filter.form.as_p }}
    {% for obj in filter %} {{ obj.name }} - ${{ obj.price }}
    {% endfor %} {% endblock %}r…r}r(h2Uh3jüubaubhO)r}r(h2X®And that's all there is to it! The ``form`` attribute contains a normal Django form, and when we iterate over the ``FilterSet`` we get the objects in the resulting queryset.h3jæh4h5h6hRh8}r(h:]h;]h<]h=]h?]uhAKhBhh-]r(hKX$And that's all there is to it! The r…r}r (h2X$And that's all there is to it! The h3jubhX)r }r (h2X``form``h8}r (h:]h;]h<]h=]h?]uh3jh-]r hKXformr…r}r(h2Uh3j ubah6h`ubhKXG attribute contains a normal Django form, and when we iterate over the r…r}r(h2XG attribute contains a normal Django form, and when we iterate over the h3jubhX)r}r(h2X ``FilterSet``h8}r(h:]h;]h<]h=]h?]uh3jh-]rhKX FilterSetr…r}r(h2Uh3jubah6h`ubhKX. we get the objects in the resulting queryset.r…r}r(h2X. we get the objects in the resulting queryset.h3jubeubeubh/)r}r(h2Uh3h0h4h5h6h7h8}r (h:]h;]h<]h=]r!h,ah?]r"hauhAK¢hBhh-]r#(hD)r$}r%(h2XOther Meta optionsr&h3jh4h5h6hHh8}r'(h:]h;]h<]h=]h?]uhAK¢hBhh-]r(hKXOther Meta optionsr)…r*}r+(h2j&h3j$ubaubh/)r,}r-(h2Uh3jh4h5h6h7h8}r.(h:]h;]h<]h=]r/h(ah?]r0hauhAK¥hBhh-]r1(hD)r2}r3(h2XOrdering using ``order_by``r4h3j,h4h5h6hHh8}r5(h:]h;]h<]h=]h?]uhAK¥hBhh-]r6(hKXOrdering using r7…r8}r9(h2XOrdering using r:h3j2ubhX)r;}r<(h2X ``order_by``r=h8}r>(h:]h;]h<]h=]h?]uh3j2h-]r?hKXorder_byr@…rA}rB(h2Uh3j;ubah6h`ubeubhO)rC}rD(h2XqYou can allow the user to control ordering by providing the ``order_by`` argument in the Filter's Meta class. ``order_by`` can be either a ``list`` or ``tuple`` of field names, in which case those are the options, or it can be a ``bool`` which, if True, indicates that all fields that the user can filter on can also be sorted on. An example or ordering using a list::h3j,h4h5h6hRh8}rE(h:]h;]h<]h=]h?]uhAK§hBhh-]rF(hKX<You can allow the user to control ordering by providing the rG…rH}rI(h2X<You can allow the user to control ordering by providing the h3jCubhX)rJ}rK(h2X ``order_by``h8}rL(h:]h;]h<]h=]h?]uh3jCh-]rMhKXorder_byrN…rO}rP(h2Uh3jJubah6h`ubhKX' argument in the Filter's Meta class. rQ…rR}rS(h2X' argument in the Filter's Meta class. h3jCubhX)rT}rU(h2X ``order_by``h8}rV(h:]h;]h<]h=]h?]uh3jCh-]rWhKXorder_byrX…rY}rZ(h2Uh3jTubah6h`ubhKX can be either a r[…r\}r](h2X can be either a h3jCubhX)r^}r_(h2X``list``h8}r`(h:]h;]h<]h=]h?]uh3jCh-]rahKXlistrb…rc}rd(h2Uh3j^ubah6h`ubhKX or re…rf}rg(h2X or h3jCubhX)rh}ri(h2X ``tuple``h8}rj(h:]h;]h<]h=]h?]uh3jCh-]rkhKXtuplerl…rm}rn(h2Uh3jhubah6h`ubhKXE of field names, in which case those are the options, or it can be a ro…rp}rq(h2XE of field names, in which case those are the options, or it can be a h3jCubhX)rr}rs(h2X``bool``h8}rt(h:]h;]h<]h=]h?]uh3jCh-]ruhKXboolrv…rw}rx(h2Uh3jrubah6h`ubhKX‚ which, if True, indicates that all fields that the user can filter on can also be sorted on. An example or ordering using a list:ry…rz}r{(h2X‚ which, if True, indicates that all fields that the user can filter on can also be sorted on. An example or ordering using a list:h3jCubeubhz)r|}r}(h2Xïimport django_filters class ProductFilter(django_filters.FilterSet): price = django_filters.NumberFilter(lookup_type='lt') class Meta: model = Product fields = ['price', 'release_date'] order_by = ['price']h3j,h4h5h6h}h8}r~(hh€h=]h<]h:]h;]h?]uhAK­hBhh-]rhKXïimport django_filters class ProductFilter(django_filters.FilterSet): price = django_filters.NumberFilter(lookup_type='lt') class Meta: model = Product fields = ['price', 'release_date'] order_by = ['price']r€…r}r‚(h2Uh3j|ubaubhO)rƒ}r„(h2XÞIf you want to control the display of items in ``order_by``, you can set it to a list or tuple of 2-tuples in the format ``(field_name, display_name)``. This lets you override the displayed names for your ordering fields::h3j,h4h5h6hRh8}r…(h:]h;]h<]h=]h?]uhAK¶hBhh-]r†(hKX/If you want to control the display of items in r‡…rˆ}r‰(h2X/If you want to control the display of items in h3jƒubhX)rŠ}r‹(h2X ``order_by``h8}rŒ(h:]h;]h<]h=]h?]uh3jƒh-]rhKXorder_byrŽ…r}r(h2Uh3jŠubah6h`ubhKX>, you can set it to a list or tuple of 2-tuples in the format r‘…r’}r“(h2X>, you can set it to a list or tuple of 2-tuples in the format h3jƒubhX)r”}r•(h2X``(field_name, display_name)``h8}r–(h:]h;]h<]h=]h?]uh3jƒh-]r—hKX(field_name, display_name)r˜…r™}rš(h2Uh3j”ubah6h`ubhKXF. This lets you override the displayed names for your ordering fields:r›…rœ}r(h2XF. This lets you override the displayed names for your ordering fields:h3jƒubeubhz)rž}rŸ(h2XMorder_by = ( ('name', 'Company Name'), ('average_rating', 'Stars'), )h3j,h4h5h6h}h8}r (hh€h=]h<]h:]h;]h?]uhAKºhBhh-]r¡hKXMorder_by = ( ('name', 'Company Name'), ('average_rating', 'Stars'), )r¢…r£}r¤(h2Uh3jžubaubhO)r¥}r¦(h2XÎNote that the default query parameter name used for ordering is ``o``. You can override this by setting an ``order_by_field`` attribute on the ``FilterSet`` class to the string value you would like to use.h3j,h4h5h6hRh8}r§(h:]h;]h<]h=]h?]uhAK¿hBhh-]r¨(hKX@Note that the default query parameter name used for ordering is r©…rª}r«(h2X@Note that the default query parameter name used for ordering is h3j¥ubhX)r¬}r­(h2X``o``h8}r®(h:]h;]h<]h=]h?]uh3j¥h-]r¯hKXo…r°}r±(h2Uh3j¬ubah6h`ubhKX'. You can override this by setting an r²…r³}r´(h2X'. You can override this by setting an h3j¥ubhX)rµ}r¶(h2X``order_by_field``h8}r·(h:]h;]h<]h=]h?]uh3j¥h-]r¸hKXorder_by_fieldr¹…rº}r»(h2Uh3jµubah6h`ubhKX attribute on the r¼…r½}r¾(h2X attribute on the h3j¥ubhX)r¿}rÀ(h2X ``FilterSet``h8}rÁ(h:]h;]h<]h=]h?]uh3j¥h-]rÂhKX FilterSetrÃ…rÄ}rÅ(h2Uh3j¿ubah6h`ubhKX1 class to the string value you would like to use.rÆ…rÇ}rÈ(h2X1 class to the string value you would like to use.h3j¥ubeubeubh/)rÉ}rÊ(h2Uh3jh4h5h6h7h8}rË(h:]h;]h<]h=]rÌhah?]rÍhauhAKÄhBhh-]rÎ(hD)rÏ}rÐ(h2XCustom Forms using ``form``rÑh3jÉh4h5h6hHh8}rÒ(h:]h;]h<]h=]h?]uhAKÄhBhh-]rÓ(hKXCustom Forms using rÔ…rÕ}rÖ(h2XCustom Forms using r×h3jÏubhX)rØ}rÙ(h2X``form``rÚh8}rÛ(h:]h;]h<]h=]h?]uh3jÏh-]rÜhKXformrÝ…rÞ}rß(h2Uh3jØubah6h`ubeubhO)rà}rá(h2XÅThe inner ``Meta`` class also takes an optional ``form`` argument. This is a form class from which ``FilterSet.form`` will subclass. This works similar to the ``form`` option on a ``ModelAdmin.``h3jÉh4h5h6hRh8}râ(h:]h;]h<]h=]h?]uhAKÆhBhh-]rã(hKX The inner rä…rå}ræ(h2X The inner h3jàubhX)rç}rè(h2X``Meta``h8}ré(h:]h;]h<]h=]h?]uh3jàh-]rêhKXMetarë…rì}rí(h2Uh3jçubah6h`ubhKX class also takes an optional rî…rï}rð(h2X class also takes an optional h3jàubhX)rñ}rò(h2X``form``h8}ró(h:]h;]h<]h=]h?]uh3jàh-]rôhKXformrõ…rö}r÷(h2Uh3jñubah6h`ubhKX, argument. This is a form class from which rø…rù}rú(h2X, argument. This is a form class from which h3jàubhX)rû}rü(h2X``FilterSet.form``h8}rý(h:]h;]h<]h=]h?]uh3jàh-]rþhKXFilterSet.formrÿ…r}r(h2Uh3jûubah6h`ubhKX+ will subclass. This works similar to the r…r}r(h2X+ will subclass. This works similar to the h3jàubhX)r}r(h2X``form``h8}r(h:]h;]h<]h=]h?]uh3jàh-]rhKXformr …r }r (h2Uh3jubah6h`ubhKX option on a r …r }r(h2X option on a h3jàubhX)r}r(h2X``ModelAdmin.``h8}r(h:]h;]h<]h=]h?]uh3jàh-]rhKX ModelAdmin.r…r}r(h2Uh3jubah6h`ubeubeubeubh/)r}r(h2Uh3h0h4h5h6h7h8}r(h:]h;]h<]h=]rh ah?]rhauhAKËhBhh-]r(hD)r}r(h2XNon-Meta optionsrh3jh4h5h6hHh8}r(h:]h;]h<]h=]h?]uhAKËhBhh-]r hKXNon-Meta optionsr!…r"}r#(h2jh3jubaubhO)r$}r%(h2XiNote that these options do not go in the Meta class, they are specified directly in your FilterSet class.r&h3jh4h5h6hRh8}r'(h:]h;]h<]h=]h?]uhAKÍhBhh-]r(hKXiNote that these options do not go in the Meta class, they are specified directly in your FilterSet class.r)…r*}r+(h2j&h3j$ubaubh/)r,}r-(h2Uh3jh4h5h6h7h8}r.(h:]h;]h<]h=]r/h#ah?]r0h auhAKÑhBhh-]r1(hD)r2}r3(h2X ``strict``r4h3j,h4h5h6hHh8}r5(h:]h;]h<]h=]h?]uhAKÑhBhh-]r6hX)r7}r8(h2j4h8}r9(h:]h;]h<]h=]h?]uh3j2h-]r:hKXstrictr;…r<}r=(h2Uh3j7ubah6h`ubaubhO)r>}r?(h2XƒThe ``strict`` option controls whether results are returned when an invalid value is specified by the user for any filter field. By default, ``strict`` is set to ``True`` meaning that an empty queryset is returned if any field contains an invalid value. You can loosen this behavior by setting ``strict`` to ``False`` which will effectively ignore a filter field if its value is invalid.h3j,h4h5h6hRh8}r@(h:]h;]h<]h=]h?]uhAKÓhBhh-]rA(hKXThe rB…rC}rD(h2XThe h3j>ubhX)rE}rF(h2X ``strict``h8}rG(h:]h;]h<]h=]h?]uh3j>h-]rHhKXstrictrI…rJ}rK(h2Uh3jEubah6h`ubhKX option controls whether results are returned when an invalid value is specified by the user for any filter field. By default, rL…rM}rN(h2X option controls whether results are returned when an invalid value is specified by the user for any filter field. By default, h3j>ubhX)rO}rP(h2X ``strict``h8}rQ(h:]h;]h<]h=]h?]uh3j>h-]rRhKXstrictrS…rT}rU(h2Uh3jOubah6h`ubhKX is set to rV…rW}rX(h2X is set to h3j>ubhX)rY}rZ(h2X``True``h8}r[(h:]h;]h<]h=]h?]uh3j>h-]r\hKXTruer]…r^}r_(h2Uh3jYubah6h`ubhKX| meaning that an empty queryset is returned if any field contains an invalid value. You can loosen this behavior by setting r`…ra}rb(h2X| meaning that an empty queryset is returned if any field contains an invalid value. You can loosen this behavior by setting h3j>ubhX)rc}rd(h2X ``strict``h8}re(h:]h;]h<]h=]h?]uh3j>h-]rfhKXstrictrg…rh}ri(h2Uh3jcubah6h`ubhKX to rj…rk}rl(h2X to h3j>ubhX)rm}rn(h2X ``False``h8}ro(h:]h;]h<]h=]h?]uh3j>h-]rphKXFalserq…rr}rs(h2Uh3jmubah6h`ubhKXF which will effectively ignore a filter field if its value is invalid.rt…ru}rv(h2XF which will effectively ignore a filter field if its value is invalid.h3j>ubeubeubeubh/)rw}rx(h2Uh3h0h4h5h6h7h8}ry(h:]h;]h<]h=]rzh$ah?]r{h auhAKÚhBhh-]r|(hD)r}}r~(h2X Overriding ``FilterSet`` methodsrh3jwh4h5h6hHh8}r€(h:]h;]h<]h=]h?]uhAKÚhBhh-]r(hKX Overriding r‚…rƒ}r„(h2X Overriding r…h3j}ubhX)r†}r‡(h2X ``FilterSet``rˆh8}r‰(h:]h;]h<]h=]h?]uh3j}h-]rŠhKX FilterSetr‹…rŒ}r(h2Uh3j†ubah6h`ubhKX methodsrŽ…r}r(h2X methodsr‘h3j}ubeubh/)r’}r“(h2Uh3jwh4h5h6h7h8}r”(h:]h;]h<]h=]r•h'ah?]r–hauhAKÝhBhh-]r—(hD)r˜}r™(h2X``get_ordering_field()``ršh3j’h4h5h6hHh8}r›(h:]h;]h<]h=]h?]uhAKÝhBhh-]rœhX)r}rž(h2jšh8}rŸ(h:]h;]h<]h=]h?]uh3j˜h-]r hKXget_ordering_field()r¡…r¢}r£(h2Uh3jubah6h`ubaubhO)r¤}r¥(h2XËIf you want to use a custom widget, or in any other way override the ordering field you can override the ``get_ordering_field()`` method on a ``FilterSet``. This method just needs to return a Form Field.h3j’h4h5h6hRh8}r¦(h:]h;]h<]h=]h?]uhAKßhBhh-]r§(hKXiIf you want to use a custom widget, or in any other way override the ordering field you can override the r¨…r©}rª(h2XiIf you want to use a custom widget, or in any other way override the ordering field you can override the h3j¤ubhX)r«}r¬(h2X``get_ordering_field()``h8}r­(h:]h;]h<]h=]h?]uh3j¤h-]r®hKXget_ordering_field()r¯…r°}r±(h2Uh3j«ubah6h`ubhKX method on a r²…r³}r´(h2X method on a h3j¤ubhX)rµ}r¶(h2X ``FilterSet``h8}r·(h:]h;]h<]h=]h?]uh3j¤h-]r¸hKX FilterSetr¹…rº}r»(h2Uh3jµubah6h`ubhKX0. This method just needs to return a Form Field.r¼…r½}r¾(h2X0. This method just needs to return a Form Field.h3j¤ubeubhO)r¿}rÀ(h2XFOrdering on multiple fields, or other complex orderings can be achieved by overriding the ``Filterset.get_order_by()`` method. This is passed the selected ``order_by`` value, and is expected to return an iterable of values to pass to ``QuerySet.order_by``. For example, to sort a ``User`` table by last name, then first name::h3j’h4h5h6hRh8}rÁ(h:]h;]h<]h=]h?]uhAKãhBhh-]rÂ(hKXZOrdering on multiple fields, or other complex orderings can be achieved by overriding the rÃ…rÄ}rÅ(h2XZOrdering on multiple fields, or other complex orderings can be achieved by overriding the h3j¿ubhX)rÆ}rÇ(h2X``Filterset.get_order_by()``h8}rÈ(h:]h;]h<]h=]h?]uh3j¿h-]rÉhKXFilterset.get_order_by()rÊ…rË}rÌ(h2Uh3jÆubah6h`ubhKX% method. This is passed the selected rÍ…rÎ}rÏ(h2X% method. This is passed the selected h3j¿ubhX)rÐ}rÑ(h2X ``order_by``h8}rÒ(h:]h;]h<]h=]h?]uh3j¿h-]rÓhKXorder_byrÔ…rÕ}rÖ(h2Uh3jÐubah6h`ubhKXC value, and is expected to return an iterable of values to pass to r×…rØ}rÙ(h2XC value, and is expected to return an iterable of values to pass to h3j¿ubhX)rÚ}rÛ(h2X``QuerySet.order_by``h8}rÜ(h:]h;]h<]h=]h?]uh3j¿h-]rÝhKXQuerySet.order_byrÞ…rß}rà(h2Uh3jÚubah6h`ubhKX. For example, to sort a rá…râ}rã(h2X. For example, to sort a h3j¿ubhX)rä}rå(h2X``User``h8}ræ(h:]h;]h<]h=]h?]uh3j¿h-]rçhKXUserrè…ré}rê(h2Uh3jäubah6h`ubhKX% table by last name, then first name:rë…rì}rí(h2X% table by last name, then first name:h3j¿ubeubhz)rî}rï(h2Xhclass UserFilter(django_filters.FilterSet): class Meta: order_by = ( ('username', 'Username'), ('last_name', 'Last Name') ) def get_order_by(self, order_value): if order_value == 'last_name': return ['last_name', 'first_name'] return super(UserFilter, self).get_order_by(order_value)h3j’h4h5h6h}h8}rð(hh€h=]h<]h:]h;]h?]uhAKéhBhh-]rñhKXhclass UserFilter(django_filters.FilterSet): class Meta: order_by = ( ('username', 'Username'), ('last_name', 'Last Name') ) def get_order_by(self, order_value): if order_value == 'last_name': return ['last_name', 'first_name'] return super(UserFilter, self).get_order_by(order_value)rò…ró}rô(h2Uh3jîubaubeubeubh/)rõ}rö(h2Uh3h0h4h5h6h7h8}r÷(h:]h;]h<]h=]røh)ah?]rùhauhAKöhBhh-]rú(hD)rû}rü(h2X Generic Viewrýh3jõh4h5h6hHh8}rþ(h:]h;]h<]h=]h?]uhAKöhBhh-]rÿhKX Generic Viewr…r}r(h2jýh3jûubaubhO)r}r(h2XIn addition to the above usage there is also a class-based generic view included in django-filter, which lives at ``django_filters.views.FilterView``. You must provide either a ``model`` or ``filterset_class`` argument, similar to ``ListView`` in Django itself::h3jõh4h5h6hRh8}r(h:]h;]h<]h=]h?]uhAKøhBhh-]r(hKXrIn addition to the above usage there is also a class-based generic view included in django-filter, which lives at r…r}r (h2XrIn addition to the above usage there is also a class-based generic view included in django-filter, which lives at h3jubhX)r }r (h2X#``django_filters.views.FilterView``h8}r (h:]h;]h<]h=]h?]uh3jh-]r hKXdjango_filters.views.FilterViewr…r}r(h2Uh3j ubah6h`ubhKX. You must provide either a r…r}r(h2X. You must provide either a h3jubhX)r}r(h2X ``model``h8}r(h:]h;]h<]h=]h?]uh3jh-]rhKXmodelr…r}r(h2Uh3jubah6h`ubhKX or r…r}r(h2X or h3jubhX)r}r(h2X``filterset_class``h8}r (h:]h;]h<]h=]h?]uh3jh-]r!hKXfilterset_classr"…r#}r$(h2Uh3jubah6h`ubhKX argument, similar to r%…r&}r'(h2X argument, similar to h3jubhX)r(}r)(h2X ``ListView``h8}r*(h:]h;]h<]h=]h?]uh3jh-]r+hKXListViewr,…r-}r.(h2Uh3j(ubah6h`ubhKX in Django itself:r/…r0}r1(h2X in Django itself:h3jubeubhz)r2}r3(h2XÔ# urls.py from django.conf.urls import patterns, url from django_filters.views import FilterView from myapp.models import Product urlpatterns = patterns('', (r'^list/$', FilterView.as_view(model=Product)), )h3jõh4h5h6h}h8}r4(hh€h=]h<]h:]h;]h?]uhAKýhBhh-]r5hKXÔ# urls.py from django.conf.urls import patterns, url from django_filters.views import FilterView from myapp.models import Product urlpatterns = patterns('', (r'^list/$', FilterView.as_view(model=Product)), )r6…r7}r8(h2Uh3j2ubaubhO)r9}r:(h2XÄYou must provide a template at ``/_filter.html`` which gets the context parameter ``filter``. Additionally, the context will contain ``object_list`` which holds the filtered queryset.h3jõh4h5h6hRh8}r;(h:]h;]h<]h=]h?]uhAMhBhh-]r<(hKXYou must provide a template at r=…r>}r?(h2XYou must provide a template at h3j9ubhX)r@}rA(h2X``/_filter.html``h8}rB(h:]h;]h<]h=]h?]uh3j9h-]rChKX/_filter.htmlrD…rE}rF(h2Uh3j@ubah6h`ubhKX" which gets the context parameter rG…rH}rI(h2X" which gets the context parameter h3j9ubhX)rJ}rK(h2X ``filter``h8}rL(h:]h;]h<]h=]h?]uh3j9h-]rMhKXfilterrN…rO}rP(h2Uh3jJubah6h`ubhKX*. Additionally, the context will contain rQ…rR}rS(h2X*. Additionally, the context will contain h3j9ubhX)rT}rU(h2X``object_list``h8}rV(h:]h;]h<]h=]h?]uh3j9h-]rWhKX object_listrX…rY}rZ(h2Uh3jTubah6h`ubhKX# which holds the filtered queryset.r[…r\}r](h2X# which holds the filtered queryset.h3j9ubeubhO)r^}r_(h2XåA legacy functional generic view is still included in django-filter, although its use is deprecated. It can be found at ``django_filters.views.object_filter``. You must provide the same arguments to it as the class based view::h3jõh4h5h6hRh8}r`(h:]h;]h<]h=]h?]uhAM hBhh-]ra(hKXyA legacy functional generic view is still included in django-filter, although its use is deprecated. It can be found at rb…rc}rd(h2XyA legacy functional generic view is still included in django-filter, although its use is deprecated. It can be found at h3j^ubhX)re}rf(h2X&``django_filters.views.object_filter``h8}rg(h:]h;]h<]h=]h?]uh3j^h-]rhhKX"django_filters.views.object_filterri…rj}rk(h2Uh3jeubah6h`ubhKXE. You must provide the same arguments to it as the class based view:rl…rm}rn(h2XE. You must provide the same arguments to it as the class based view:h3j^ubeubhz)ro}rp(h2X¿# urls.py from django.conf.urls import patterns, url from myapp.models import Product urlpatterns = patterns('', (r'^list/$', 'django_filters.views.object_filter', {'model': Product}), )h3jõh4h5h6h}h8}rq(hh€h=]h<]h:]h;]h?]uhAMhBhh-]rrhKX¿# urls.py from django.conf.urls import patterns, url from myapp.models import Product urlpatterns = patterns('', (r'^list/$', 'django_filters.views.object_filter', {'model': Product}), )rs…rt}ru(h2Uh3joubaubhO)rv}rw(h2XbThe needed template and its context variables will also be the same as the class-based view above.rxh3jõh4h5h6hRh8}ry(h:]h;]h<]h=]h?]uhAMhBhh-]rzhKXbThe needed template and its context variables will also be the same as the class-based view above.r{…r|}r}(h2jxh3jvubaubeubeubah2UU transformerr~NU footnote_refsr}r€Urefnamesr}r‚X django's orm]rƒhßasUsymbol_footnotesr„]r…Uautofootnote_refsr†]r‡Usymbol_footnote_refsrˆ]r‰U citationsrŠ]r‹hBhU current_linerŒNUtransform_messagesr]rŽUreporterrNUid_startrKU autofootnotesr‘]r’U citation_refsr“}r”Uindirect_targetsr•]r–Usettingsr—(cdocutils.frontend Values r˜or™}rš(Ufootnote_backlinksr›KUrecord_dependenciesrœNU rfc_base_urlrUhttp://tools.ietf.org/html/ržU tracebackrŸˆUpep_referencesr NUstrip_commentsr¡NU toc_backlinksr¢Uentryr£U language_coder¤Uenr¥U datestampr¦NU report_levelr§KU _destinationr¨NU halt_levelr©KU strip_classesrªNhHNUerror_encoding_error_handlerr«Ubackslashreplacer¬Udebugr­NUembed_stylesheetr®‰Uoutput_encoding_error_handlerr¯Ustrictr°U sectnum_xformr±KUdump_transformsr²NU docinfo_xformr³KUwarning_streamr´NUpep_file_url_templaterµUpep-%04dr¶Uexit_status_levelr·KUconfigr¸NUstrict_visitorr¹NUcloak_email_addressesrºˆUtrim_footnote_reference_spacer»‰Uenvr¼NUdump_pseudo_xmlr½NUexpose_internalsr¾NUsectsubtitle_xformr¿‰U source_linkrÀNUrfc_referencesrÁNUoutput_encodingrÂUutf-8rÃU source_urlrÄNUinput_encodingrÅU utf-8-sigrÆU_disable_configrÇNU id_prefixrÈUU tab_widthrÉKUerror_encodingrÊUUTF-8rËU_sourcerÌh5Ugettext_compactr͈U generatorrÎNUdump_internalsrÏNU smart_quotesrЉU pep_base_urlrÑUhttp://www.python.org/dev/peps/rÒUsyntax_highlightrÓUlongrÔUinput_encoding_error_handlerrÕj°Uauto_id_prefixrÖUidr×Udoctitle_xformr؉Ustrip_elements_with_classesrÙNU _config_filesrÚ]Ufile_insertion_enabledrÛˆU raw_enabledrÜKU dump_settingsrÝNubUsymbol_footnote_startrÞKUidsrß}rà(h&jæh+jœh%jÉh(j,h!hîhjÉh'j’h jh#j,h,jh$jwh)jõh"h0h*hdhh…uUsubstitution_namesrá}râh6hBh8}rã(h:]h=]h<]Usourceh5h;]h?]uU footnotesrä]råUrefidsræ}rçub.django-filter-0.11.0/docs/_build/html/0000755000076500000240000000000012563340512020236 5ustar carltonstaff00000000000000django-filter-0.11.0/docs/_build/html/.buildinfo0000644000076500000240000000034612436054335022221 0ustar carltonstaff00000000000000# Sphinx build info version 1 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. config: 882f14951f7370aee1cee594c96e3783 tags: 645f666f9bcd5a90fca523b33c5a78b7 django-filter-0.11.0/docs/_build/html/_sources/0000755000076500000240000000000012563340512022060 5ustar carltonstaff00000000000000django-filter-0.11.0/docs/_build/html/_sources/index.txt0000644000076500000240000000060412410601557023730 0ustar carltonstaff00000000000000============= django-filter ============= Django-filter is a generic, reusable application to alleviate writing some of the more mundane bits of view code. Specifically, it allows users to filter down a queryset based on a model's fields, displaying the form to let them do this. Contents: .. toctree:: :maxdepth: 1 install usage ref/filters ref/widgets tests django-filter-0.11.0/docs/_build/html/_sources/install.txt0000644000076500000240000000031512410601557024266 0ustar carltonstaff00000000000000Installing django-filter ------------------------ To install, simply place the ``django_filters`` directory somewhere on your ``PYTHONPATH``, and then add ``'django_filters'`` to your ``INSTALLED_APPS``. django-filter-0.11.0/docs/_build/html/_sources/ref/0000755000076500000240000000000012563340512022634 5ustar carltonstaff00000000000000django-filter-0.11.0/docs/_build/html/_sources/ref/filters.txt0000644000076500000240000001352312436047311025051 0ustar carltonstaff00000000000000Filter Reference ================ This is a reference document with a list of the filters and their arguments. Filters ------- ``CharFilter`` ~~~~~~~~~~~~~~ This filter does simple character matches, used with ``CharField`` and ``TextField`` by default. ``BooleanFilter`` ~~~~~~~~~~~~~~~~~ This filter matches a boolean, either ``True`` or ``False``, used with ``BooleanField`` and ``NullBooleanField`` by default. ``ChoiceFilter`` ~~~~~~~~~~~~~~~~ This filter matches an item of any type by choices, used with any field that has ``choices``. ``TypedChoiceFilter`` ~~~~~~~~~~~~~~~~~~~~~ The same as ``ChoiceFilter`` with the added possibility to convert value to match against. This could be done by using `coerce` parameter. An example use-case is limiting boolean choices to match against so only some predefined strings could be used as input of a boolean filter:: import django_filters from distutils.util import strtobool BOOLEAN_CHOICES = (('false', 'False'), ('true', 'True'),) class YourFilterSet(django_filters.FilterSet): ... flag = django_filters.TypedChoiceFilter(choices=BOOLEAN_CHOICES, coerce=strtobool) ``MultipleChoiceFilter`` ~~~~~~~~~~~~~~~~~~~~~~~~ The same as ``ChoiceFilter`` except the user can select multiple items and it selects the OR of all the choices. Advanced Use: Depending on your application logic, when all or no choices are selected, filtering may be a noop. In this case you may wish to avoid the filtering overhead, particularly of the `distinct` call. Set `always_filter` to False after instantiation to enable the default `is_noop` test. Override `is_noop` if you require a different test for your application. ``DateFilter`` ~~~~~~~~~~~~~~ Matches on a date. Used with ``DateField`` by default. ``DateTimeFilter`` ~~~~~~~~~~~~~~~~~~ Matches on a date and time. Used with ``DateTimeField`` by default. ``TimeFilter`` ~~~~~~~~~~~~~~ Matches on a time. Used with ``TimeField`` by default. ``ModelChoiceFilter`` ~~~~~~~~~~~~~~~~~~~~~ Similar to a ``ChoiceFilter`` except it works with related models, used for ``ForeignKey`` by default. ``ModelMultipleChoiceFilter`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Similar to a ``MultipleChoiceFilter`` except it works with related models, used for ``ManyToManyField`` by default. ``NumberFilter`` ~~~~~~~~~~~~~~~~ Filters based on a numerical value, used with ``IntegerField``, ``FloatField``, and ``DecimalField`` by default. ``RangeFilter`` ~~~~~~~~~~~~~~~ Filters where a value is between two numerical values, or greater than a minimum or less than a maximum where only one limit value is provided. :: class F(FilterSet): """Filter for Books by Price""" price = RangeFilter() class Meta: model = Book fields = ['price'] qs = Book.objects.all().order_by('title') # Range: Books between 5€ and 15€ f = F({'price_0': '5', 'price_1': '15'}, queryset=qs) # Min-Only: Books costing more the 11€ f = F({'price_0': '11'}, queryset=qs) # Max-Only: Books costing less than 19€ f = F({'price_1': '19'}, queryset=qs) ``DateRangeFilter`` ~~~~~~~~~~~~~~~~~~~ Filter similar to the admin changelist date one, it has a number of common selections for working with date fields. ``AllValuesFilter`` ~~~~~~~~~~~~~~~~~~~ This is a ``ChoiceFilter`` whose choices are the current values in the database. So if in the DB for the given field you have values of 5, 7, and 9 each of those is present as an option. This is similar to the default behavior of the admin. ``MethodFilter`` ~~~~~~~~~~~~~~~~~~~ This is a ``Filter`` that will allow you to run a method that exists on the filter set that this filter is a property of. Set the `action` to a string that will map to a method on the filter set class. Core Arguments -------------- ``name`` ~~~~~~~~ The name of the field this filter is supposed to filter on, if this is not provided it automatically becomes the filter's name on the ``FilterSet``. ``label`` ~~~~~~~~~ The label as it will apear in the HTML, analogous to a form field's label argument. ``widget`` ~~~~~~~~~~ The django.form Widget class which will represent the ``Filter``. In addition to the widgets that are included with Django that you can use there are additional ones that django-filter provides which may be useful: * ``django_filters.widgets.LinkWidget`` -- this displays the options in a mannner similar to the way the Django Admin does, as a series of links. The link for the selected option will have ``class="selected"``. ``action`` ~~~~~~~~~~ An optional callable that tells the filter how to handle the queryset. It recieves a ``QuerySet`` and the value to filter on and should return a ``Queryset`` that is filtered appropriately. ``lookup_type`` ~~~~~~~~~~~~~~~ The type of lookup that should be performed using the [Django ORM](https://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookups "Django's ORM Lookups"). All the normal options are allowed, and should be provided as a string. You can also provide either ``None`` or a ``list`` or a ``tuple``. If ``None`` is provided, then the user can select the lookup type from all the ones available in the Django ORM. If a ``list`` or ``tuple`` is provided, then the user can select from those options. ``distinct`` ~~~~~~~~~~~~ A boolean value that specifies whether the Filter will use distinct on the queryset. This option can be used to eliminate duplicate results when using filters that span related models. Defaults to ``False``. ``exclude`` ~~~~~~~~~~~ A boolean value that specifies whether the Filter should use ``filter`` or ``exclude`` on the queryset. Defaults to ``False``. ``**kwargs`` ~~~~~~~~~~~~ Any extra keyword arguments will be provided to the accompanying form Field. This can be used to provide arguments like ``choices`` or ``queryset``. django-filter-0.11.0/docs/_build/html/_sources/ref/widgets.txt0000644000076500000240000000121212411012542025026 0ustar carltonstaff00000000000000Widget Reference ================ This is a reference document with a list of the provided widgets and their arguments. ``LinkWidget`` ~~~~~~~~~~~~~~ This widget renders each option as a link, instead of an actual . It has one method that you can overide for additional customizability. ``option_string()`` should return a string with 3 Python keyword argument placeholders:: 1. ``attrs``: This is a string with all the attributes that will be on the final ``
    `` tag. 2. ``query_string``: This is the query string for use in the ``href`` option on the ```` elemeent. 3. ``label``: This is the text to be displayed to the user. django-filter-0.11.0/docs/_build/html/_sources/tests.txt0000644000076500000240000000225112410601557023763 0ustar carltonstaff00000000000000Running the django-filter tests =============================== The easiest way to run the django-filter tests is to check out the source code into a virtualenv, where you can install the test dependencies. django-filter uses a custom test runner to locate all of the tests, so a wrapper script is available to set up and run the test suite. .. note:: The following assumes you have `virtualenv`__ and `git`__ installed. __ http://www.virtualenv.org __ http://git-scm.com Set up a virtualenv for the test suite -------------------------------------- Run the following to create a new virtualenv to run the test suite in:: virtualenv django-filter-tests cd django-filter-tests . bin/activate Get a copy of django-filter --------------------------- Get the django-filter source code using the following command:: git clone https://github.com/alex/django-filter.git Switch to the django-filter directory:: cd django-filter Install the test dependencies ----------------------------- Run the following to install the test dependencies within the virutalenv:: pip install -r requirements/test.txt Run the django-filter tests:: python runtests.py django-filter-0.11.0/docs/_build/html/_sources/usage.txt0000644000076500000240000002235112435155541023734 0ustar carltonstaff00000000000000Using django-filter =================== Django-filter provides a simple way to filter down a queryset based on parameters a user provides. Say we have a ``Product`` model and we want to let our users filter which products they see on a list page. The model --------- Let's start with our model:: from django.db import models class Product(models.Model): name = models.CharField(max_length=255) price = models.DecimalField() description = models.TextField() release_date = models.DateField() manufacturer = models.ForeignKey(Manufacturer) The filter ---------- We have a number of fields and we want to let our users filter based on the price or the release_date. We create a ``FilterSet`` for this:: import django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['price', 'release_date'] As you can see this uses a very similar API to Django's ``ModelForm``. Just like with a ``ModelForm`` we can also override filters, or add new ones using a declarative syntax:: import django_filters class ProductFilter(django_filters.FilterSet): price = django_filters.NumberFilter(lookup_type='lt') class Meta: model = Product fields = ['price', 'release_date'] Filters take a ``lookup_type`` argument which specifies what lookup type to use with `Django's ORM`_. So here when a user entered a price it would show all Products with a price less than that. .. _`Django's ORM`: https://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookups **It's quite common to forget to set lookup type for `CharField`s/`TextField`s and wonder why search for "foo" doesn't return result for "foobar". It's because default lookup type is exact text, but you probably want `icontains` lookup field.** The FilterSet Meta class fields can additionally be set using a Dictionary to specify multiple ``lookup_type`` filters without significant code duplication:: import django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = {'price': ['lt', 'gt'], 'release_date': ['exact'], } The above would generate 'price__lt', 'price__gt' and 'release_date' filters. The filter lookup type keyword 'exact' is the default and therefore never added to a filter name. Items in the ``fields`` sequence in the ``Meta`` class may include "relationship paths" using Django's ``__`` syntax to filter on fields on a related model:: class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['manufacturer__country'] Filters also take any arbitrary keyword arguments which get passed onto the ``django.forms.Field`` initializer. These extra keyword arguments get stored in ``Filter.extra``, so it's possible to override the initializer of a ``FilterSet`` to add extra ones:: class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['manufacturer'] def __init__(self, *args, **kwargs): super(ProductFilter, self).__init__(*args, **kwargs) self.filters['manufacturer'].extra.update( {'empty_label': 'All Manufacturers'}) Like ``django.contrib.admin.ModelAdmin``, it is possible to override default filters for all the models fields of the same kind using ``filter_overrides``:: class ProductFilter(django_filters.FilterSet): filter_overrides = { models.CharField: { 'filter_class': django_filters.CharFilter, 'extra': lambda f: { 'lookup_type': 'icontains', } } } class Meta: model = Product fields = ['name'] The view -------- Now we need to write a view:: def product_list(request): f = ProductFilter(request.GET, queryset=Product.objects.all()) return render_to_response('my_app/template.html', {'filter': f}) If a queryset argument isn't provided then all the items in the default manager of the model will be used. If you want to access the filtered objects in your views, for example if you want to paginate them, you can do that. They are in f.qs The URL conf ------------ We need a URL pattern to call the view:: url(r'^list$', views.product_list) The template ------------ And lastly we need a template:: {% extends "base.html" %} {% block content %}
    {{ filter.form.as_p }}
    {% for obj in filter %} {{ obj.name }} - ${{ obj.price }}
    {% endfor %} {% endblock %} And that's all there is to it! The ``form`` attribute contains a normal Django form, and when we iterate over the ``FilterSet`` we get the objects in the resulting queryset. Other Meta options ------------------ Ordering using ``order_by`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can allow the user to control ordering by providing the ``order_by`` argument in the Filter's Meta class. ``order_by`` can be either a ``list`` or ``tuple`` of field names, in which case those are the options, or it can be a ``bool`` which, if True, indicates that all fields that the user can filter on can also be sorted on. An example or ordering using a list:: import django_filters class ProductFilter(django_filters.FilterSet): price = django_filters.NumberFilter(lookup_type='lt') class Meta: model = Product fields = ['price', 'release_date'] order_by = ['price'] If you want to control the display of items in ``order_by``, you can set it to a list or tuple of 2-tuples in the format ``(field_name, display_name)``. This lets you override the displayed names for your ordering fields:: order_by = ( ('name', 'Company Name'), ('average_rating', 'Stars'), ) Note that the default query parameter name used for ordering is ``o``. You can override this by setting an ``order_by_field`` attribute on the ``FilterSet`` class to the string value you would like to use. Custom Forms using ``form`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ The inner ``Meta`` class also takes an optional ``form`` argument. This is a form class from which ``FilterSet.form`` will subclass. This works similar to the ``form`` option on a ``ModelAdmin.`` Non-Meta options ---------------- Note that these options do not go in the Meta class, they are specified directly in your FilterSet class. ``strict`` ~~~~~~~~~~ The ``strict`` option controls whether results are returned when an invalid value is specified by the user for any filter field. By default, ``strict`` is set to ``True`` meaning that an empty queryset is returned if any field contains an invalid value. You can loosen this behavior by setting ``strict`` to ``False`` which will effectively ignore a filter field if its value is invalid. Overriding ``FilterSet`` methods -------------------------------- ``get_ordering_field()`` ~~~~~~~~~~~~~~~~~~~~~~~~ If you want to use a custom widget, or in any other way override the ordering field you can override the ``get_ordering_field()`` method on a ``FilterSet``. This method just needs to return a Form Field. Ordering on multiple fields, or other complex orderings can be achieved by overriding the ``Filterset.get_order_by()`` method. This is passed the selected ``order_by`` value, and is expected to return an iterable of values to pass to ``QuerySet.order_by``. For example, to sort a ``User`` table by last name, then first name:: class UserFilter(django_filters.FilterSet): class Meta: order_by = ( ('username', 'Username'), ('last_name', 'Last Name') ) def get_order_by(self, order_value): if order_value == 'last_name': return ['last_name', 'first_name'] return super(UserFilter, self).get_order_by(order_value) Generic View ------------ In addition to the above usage there is also a class-based generic view included in django-filter, which lives at ``django_filters.views.FilterView``. You must provide either a ``model`` or ``filterset_class`` argument, similar to ``ListView`` in Django itself:: # urls.py from django.conf.urls import patterns, url from django_filters.views import FilterView from myapp.models import Product urlpatterns = patterns('', (r'^list/$', FilterView.as_view(model=Product)), ) You must provide a template at ``/_filter.html`` which gets the context parameter ``filter``. Additionally, the context will contain ``object_list`` which holds the filtered queryset. A legacy functional generic view is still included in django-filter, although its use is deprecated. It can be found at ``django_filters.views.object_filter``. You must provide the same arguments to it as the class based view:: # urls.py from django.conf.urls import patterns, url from myapp.models import Product urlpatterns = patterns('', (r'^list/$', 'django_filters.views.object_filter', {'model': Product}), ) The needed template and its context variables will also be the same as the class-based view above. django-filter-0.11.0/docs/_build/html/_static/0000755000076500000240000000000012563340512021664 5ustar carltonstaff00000000000000django-filter-0.11.0/docs/_build/html/_static/ajax-loader.gif0000644000076500000240000000124112435161671024545 0ustar carltonstaff00000000000000GIF89aòÿÿÿU|ÆÖßN€U|l–®Š«¾™¶Æ!þCreated with ajaxload.info!ù !ÿ NETSCAPE2.0,3ºÜþ0ÊIkc:œN˜f E±1º™Á¶.`ÄÂqÐ-[9ݦ9 JkçH!ù ,4ºÜþNŒ! „ »°æŠDqBQT`1 `LE[¨|µußía€ ×â†C²%$*!ù ,6º2#+ÊAÈÌ”V/…côNñIBa˜«pð ̳½ƨ+YíüƒÃ2©dŸ¿!ù ,3ºb%+Ê2†‘ìœV_…‹¦ …! 1D‡aªF‚°ÑbR]ó=08,Ȥr9L!ù ,2ºr'+JçdðóL &vÃ`\bT”…„¹hYB)ÏÊ@é<Ã&,ȤR’!ù ,3º Â9ãtç¼Úž0Çà!.B¶ÊW¬¢1  sa»°5÷•0° ‰»Ÿm)J!ù ,2ºÜþð ÙœU]šîÚqp•`ˆÝaœÝ4–…AFÅ0`›¶ Â@›1€ÂÖΑ!ù ,2ºÜþ0ÊI«eBÔœ)×à ŽÇq10©Ê°®PÂaVÚ¥ ub‚ž[;django-filter-0.11.0/docs/_build/html/_static/basic.css0000644000076500000240000002040412436054335023463 0ustar carltonstaff00000000000000/* * basic.css * ~~~~~~~~~ * * Sphinx stylesheet -- basic theme. * * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /* -- main layout ----------------------------------------------------------- */ div.clearer { clear: both; } /* -- relbar ---------------------------------------------------------------- */ div.related { width: 100%; font-size: 90%; } div.related h3 { display: none; } div.related ul { margin: 0; padding: 0 0 0 10px; list-style: none; } div.related li { display: inline; } div.related li.right { float: right; margin-right: 5px; } /* -- sidebar --------------------------------------------------------------- */ div.sphinxsidebarwrapper { padding: 10px 5px 0 10px; } div.sphinxsidebar { float: left; width: 230px; margin-left: -100%; font-size: 90%; } div.sphinxsidebar ul { list-style: none; } div.sphinxsidebar ul ul, div.sphinxsidebar ul.want-points { margin-left: 20px; list-style: square; } div.sphinxsidebar ul ul { margin-top: 0; margin-bottom: 0; } div.sphinxsidebar form { margin-top: 10px; } div.sphinxsidebar input { border: 1px solid #98dbcc; font-family: sans-serif; font-size: 1em; } div.sphinxsidebar #searchbox input[type="text"] { width: 170px; } div.sphinxsidebar #searchbox input[type="submit"] { width: 30px; } img { border: 0; max-width: 100%; } /* -- search page ----------------------------------------------------------- */ ul.search { margin: 10px 0 0 20px; padding: 0; } ul.search li { padding: 5px 0 5px 20px; background-image: url(file.png); background-repeat: no-repeat; background-position: 0 7px; } ul.search li a { font-weight: bold; } ul.search li div.context { color: #888; margin: 2px 0 0 30px; text-align: left; } ul.keywordmatches li.goodmatch a { font-weight: bold; } /* -- index page ------------------------------------------------------------ */ table.contentstable { width: 90%; } table.contentstable p.biglink { line-height: 150%; } a.biglink { font-size: 1.3em; } span.linkdescr { font-style: italic; padding-top: 5px; font-size: 90%; } /* -- general index --------------------------------------------------------- */ table.indextable { width: 100%; } table.indextable td { text-align: left; vertical-align: top; } table.indextable dl, table.indextable dd { margin-top: 0; margin-bottom: 0; } table.indextable tr.pcap { height: 10px; } table.indextable tr.cap { margin-top: 10px; background-color: #f2f2f2; } img.toggler { margin-right: 3px; margin-top: 3px; cursor: pointer; } div.modindex-jumpbox { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; margin: 1em 0 1em 0; padding: 0.4em; } div.genindex-jumpbox { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; margin: 1em 0 1em 0; padding: 0.4em; } /* -- general body styles --------------------------------------------------- */ a.headerlink { visibility: hidden; } h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink { visibility: visible; } div.body p.caption { text-align: inherit; } div.body td { text-align: left; } .field-list ul { padding-left: 1em; } .first { margin-top: 0 !important; } p.rubric { margin-top: 30px; font-weight: bold; } img.align-left, .figure.align-left, object.align-left { clear: left; float: left; margin-right: 1em; } img.align-right, .figure.align-right, object.align-right { clear: right; float: right; margin-left: 1em; } img.align-center, .figure.align-center, object.align-center { display: block; margin-left: auto; margin-right: auto; } .align-left { text-align: left; } .align-center { text-align: center; } .align-right { text-align: right; } /* -- sidebars -------------------------------------------------------------- */ div.sidebar { margin: 0 0 0.5em 1em; border: 1px solid #ddb; padding: 7px 7px 0 7px; background-color: #ffe; width: 40%; float: right; } p.sidebar-title { font-weight: bold; } /* -- topics ---------------------------------------------------------------- */ div.topic { border: 1px solid #ccc; padding: 7px 7px 0 7px; margin: 10px 0 10px 0; } p.topic-title { font-size: 1.1em; font-weight: bold; margin-top: 10px; } /* -- admonitions ----------------------------------------------------------- */ div.admonition { margin-top: 10px; margin-bottom: 10px; padding: 7px; } div.admonition dt { font-weight: bold; } div.admonition dl { margin-bottom: 0; } p.admonition-title { margin: 0px 10px 5px 0px; font-weight: bold; } div.body p.centered { text-align: center; margin-top: 25px; } /* -- tables ---------------------------------------------------------------- */ table.docutils { border: 0; border-collapse: collapse; } table.docutils td, table.docutils th { padding: 1px 8px 1px 5px; border-top: 0; border-left: 0; border-right: 0; border-bottom: 1px solid #aaa; } table.field-list td, table.field-list th { border: 0 !important; } table.footnote td, table.footnote th { border: 0 !important; } th { text-align: left; padding-right: 5px; } table.citation { border-left: solid 1px gray; margin-left: 1px; } table.citation td { border-bottom: none; } /* -- other body styles ----------------------------------------------------- */ ol.arabic { list-style: decimal; } ol.loweralpha { list-style: lower-alpha; } ol.upperalpha { list-style: upper-alpha; } ol.lowerroman { list-style: lower-roman; } ol.upperroman { list-style: upper-roman; } dl { margin-bottom: 15px; } dd p { margin-top: 0px; } dd ul, dd table { margin-bottom: 10px; } dd { margin-top: 3px; margin-bottom: 10px; margin-left: 30px; } dt:target, .highlighted { background-color: #fbe54e; } dl.glossary dt { font-weight: bold; font-size: 1.1em; } .field-list ul { margin: 0; padding-left: 1em; } .field-list p { margin: 0; } .optional { font-size: 1.3em; } .versionmodified { font-style: italic; } .system-message { background-color: #fda; padding: 5px; border: 3px solid red; } .footnote:target { background-color: #ffa; } .line-block { display: block; margin-top: 1em; margin-bottom: 1em; } .line-block .line-block { margin-top: 0; margin-bottom: 0; margin-left: 1.5em; } .guilabel, .menuselection { font-family: sans-serif; } .accelerator { text-decoration: underline; } .classifier { font-style: oblique; } abbr, acronym { border-bottom: dotted 1px; cursor: help; } /* -- code displays --------------------------------------------------------- */ pre { overflow: auto; overflow-y: hidden; /* fixes display issues on Chrome browsers */ } td.linenos pre { padding: 5px 0px; border: 0; background-color: transparent; color: #aaa; } table.highlighttable { margin-left: 0.5em; } table.highlighttable td { padding: 0 0.5em 0 0.5em; } tt.descname { background-color: transparent; font-weight: bold; font-size: 1.2em; } tt.descclassname { background-color: transparent; } tt.xref, a tt { background-color: transparent; font-weight: bold; } h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt { background-color: transparent; } .viewcode-link { float: right; } .viewcode-back { float: right; font-family: sans-serif; } div.viewcode-block:target { margin: -1px -10px; padding: 0 10px; } /* -- math display ---------------------------------------------------------- */ img.math { vertical-align: middle; } div.body div.math p { text-align: center; } span.eqno { float: right; } /* -- printout stylesheet --------------------------------------------------- */ @media print { div.document, div.documentwrapper, div.bodywrapper { margin: 0 !important; width: 100%; } div.sphinxsidebar, div.related, div.footer, #top-link { display: none; } }django-filter-0.11.0/docs/_build/html/_static/comment-bright.png0000644000076500000240000000665412435161671025331 0ustar carltonstaff00000000000000‰PNG  IHDRóÿa OiCCPPhotoshop ICC profilexÚSgTSé=÷ÞôBKˆ€”KoR RB‹€‘&*! Jˆ!¡ÙQÁEEÈ ˆŽŽ€ŒQ, Š Øä!¢Žƒ£ˆŠÊûá{£kÖ¼÷æÍþµ×>ç¬ó³ÏÀ –H3Q5€ ©BàƒÇÄÆáä.@ $p³d!sý#ø~<<+"À¾xÓ ÀM›À0‡ÿêB™\€„Àt‘8K€@zŽB¦@F€˜&S `ËcbãP-`'æÓ€ø™{[”! ‘ eˆDh;¬ÏVŠEX0fKÄ9Ø-0IWfH°·ÀÎ ² 0Qˆ…){`È##x„™FòW<ñ+®ç*x™²<¹$9E[-qWW.(ÎI+6aaš@.Ây™24àóÌ ‘àƒóýxήÎÎ6޶_-ê¿ÿ"bbãþåÏ«p@át~Ñþ,/³€;€mþ¢%îh^  u÷‹f²@µ éÚWópø~<ß5°j>{‘-¨]cöK'XtÀâ÷ò»oÁÔ(€hƒáÏwÿï?ýG %€fI’q^D$.Tʳ?ÇD *°AôÁ,ÀÁÜÁ ü`6„B$ÄÂBB d€r`)¬‚B(†Í°*`/Ô@4ÀQh†“p.ÂU¸=púažÁ(¼ AÈa!ÚˆbŠX#Ž™…ø!ÁH‹$ ɈQ"K‘5H1RŠT UHò=r9‡\Fº‘;È2‚ü†¼G1”²Q=Ô µC¹¨7„F¢ Ðdt1š ›Ðr´=Œ6¡çЫhÚ>CÇ0Àè3Äl0.ÆÃB±8, “c˱"¬ «Æ°V¬»‰õcϱwEÀ 6wB aAHXLXNØH¨ $4Ú 7 „QÂ'"“¨K´&ºùÄb21‡XH,#Ö/{ˆCÄ7$‰C2'¹I±¤TÒÒFÒnR#é,©›4H#“ÉÚdk²9”, +È…ääÃä3ää!ò[ b@q¤øSâ(RÊjJåå4åe˜2AU£šRݨ¡T5ZB­¡¶R¯Q‡¨4uš9̓IK¥­¢•Óhh÷i¯ètºÝ•N—ÐWÒËéGè—èôw †ƒÇˆg(›gw¯˜L¦Ó‹ÇT071ë˜ç™™oUX*¶*|‘Ê •J•&•*/T©ª¦ªÞª UóUËT©^S}®FU3Sã© Ô–«UªPëSSg©;¨‡ªg¨oT?¤~Yý‰YÃLÃOC¤Q ±_ã¼Æ c³x,!k «†u5Ä&±ÍÙ|v*»˜ý»‹=ª©¡9C3J3W³Ró”f?ã˜qøœtN ç(§—ó~ŠÞï)â)¦4L¹1e\kª–—–X«H«Q«Gë½6®í§¦½E»YûAÇJ'\'GgÎçSÙSݧ §M=:õ®.ªk¥¡»Dw¿n§î˜ž¾^€žLo§Þy½çú}/ýTýmú§õG X³ $Û Î<Å5qo</ÇÛñQC]Ã@C¥a•a—á„‘¹Ñ<£ÕFFŒiÆ\ã$ãmÆmÆ£&&!&KMêMîšRM¹¦)¦;L;LÇÍÌÍ¢ÍÖ™5›=1×2ç›ç›×›ß·`ZxZ,¶¨¶¸eI²äZ¦Yî¶¼n…Z9Y¥XUZ]³F­­%Ö»­»§§¹N“N«žÖgðñ¶É¶©·°åØÛ®¶m¶}agbg·Å®Ã“}º}ý= ‡Ù«Z~s´r:V:ޚΜî?}Åô–é/gXÏÏØ3ã¶Ë)ÄiS›ÓGgg¹sƒóˆ‹‰K‚Ë.—>.›ÆÝȽäJtõq]ázÒõ›³›Âí¨Û¯î6îiî‡ÜŸÌ4Ÿ)žY3sÐÃÈCàQåÑ? Ÿ•0k߬~OCOgµç#/c/‘W­×°·¥wª÷aï>ö>rŸã>ã<7Þ2ÞY_Ì7À·È·ËOÃož_…ßC#ÿdÿzÿѧ€%g‰A[ûøz|!¿Ž?:Ûeö²ÙíAŒ ¹AA‚­‚åÁ­!hÈì­!÷ç˜Î‘Îi…P~èÖÐaæa‹Ã~ '…‡…W†?ŽpˆXÑ1—5wÑÜCsßDúD–DÞ›g1O9¯-J5*>ª.j<Ú7º4º?Æ.fYÌÕXXIlK9.*®6nl¾ßüíó‡ââ ã{˜/È]py¡ÎÂô…§©.,:–@LˆN8”ðA*¨Œ%òw%Ž yÂÂg"/Ñ6шØC\*NòH*Mz’쑼5y$Å3¥,幄'©¼L LÝ›:žšv m2=:½1ƒ’‘qBª!M“¶gêgæfvˬe…²þÅn‹·/•Ék³¬Y- ¶B¦èTZ(×*²geWf¿Í‰Ê9–«ž+Íí̳ÊÛ7œïŸÿíÂá’¶¥†KW-X潬j9²‰Š®Û—Ø(Üxå‡oÊ¿™Ü”´©«Ä¹dÏfÒféæÞ-ž[–ª—æ—n ÙÚ´ ßV´íõöEÛ/—Í(Û»ƒ¶C¹£¿<¸¼e§ÉÎÍ;?T¤TôTúT6îÒݵa×ønÑî{¼ö4ìÕÛ[¼÷ý>ɾÛUUMÕfÕeûIû³÷?®‰ªéø–ûm]­NmqíÇÒý#¶×¹ÔÕÒ=TRÖ+ëGǾþïw- 6 UœÆâ#pDyäé÷ ß÷ :ÚvŒ{¬áÓvg/jBšòšF›Sšû[b[ºOÌ>ÑÖêÞzüGÛœ499â?rýéü§CÏdÏ&žþ¢þË®/~øÕë×Îјѡ—ò—“¿m|¥ýêÀë¯ÛÆÂƾÉx31^ôVûíÁwÜwï£ßOä| (ÿhù±õSЧû“““ÿ˜óüc3-ÛbKGDÿÿÿ ½§“ pHYs  šœtIMEÚ 6 B©\<ÞIDAT8Ë…’Kh]e…¿½ÿs1mAÛÄÚ`j‚Ïh[-ˆE(FEŠÁaAœ! bI« àÈ*–BX‘"Ø4)NŠõUR‚Zˆ¹­!’×Mhj“›ssÎùÿíà–¨àãmØ‹Å^‹-\ggßÏ ÷ßì]o|ÑÑÒ¬[3±¶4§Á§6»”û©òèø¯×>zd‘¿ ]½#Œ»î8ÙþüáÇOݺ±t{5·uIÍXN!I=@Vf¾®Ÿ=v×ÀÞþ1ûº}e>;ØÉö×fvìénøvËÍÅxaÉHrÏʪJ’¦Fȹ`œÈðDò¹WZ®]ÀžSíýŸø%S)ÌWAÌœb¹ |0K=âSo7D†~\~qâÍ-ïÀËŸ\ùaóMÅ“Z,S'*æô™‘È} óF`—†ÎNnzæ674¸öËUÈç¬ó³ÏÀ –H3Q5€ ©BàƒÇÄÆáä.@ $p³d!sý#ø~<<+"À¾xÓ ÀM›À0‡ÿêB™\€„Àt‘8K€@zŽB¦@F€˜&S `ËcbãP-`'æÓ€ø™{[”! ‘ eˆDh;¬ÏVŠEX0fKÄ9Ø-0IWfH°·ÀÎ ² 0Qˆ…){`È##x„™FòW<ñ+®ç*x™²<¹$9E[-qWW.(ÎI+6aaš@.Ây™24àóÌ ‘àƒóýxήÎÎ6޶_-ê¿ÿ"bbãþåÏ«p@át~Ñþ,/³€;€mþ¢%îh^  u÷‹f²@µ éÚWópø~<ß5°j>{‘-¨]cöK'XtÀâ÷ò»oÁÔ(€hƒáÏwÿï?ýG %€fI’q^D$.Tʳ?ÇD *°AôÁ,ÀÁÜÁ ü`6„B$ÄÂBB d€r`)¬‚B(†Í°*`/Ô@4ÀQh†“p.ÂU¸=púažÁ(¼ AÈa!ÚˆbŠX#Ž™…ø!ÁH‹$ ɈQ"K‘5H1RŠT UHò=r9‡\Fº‘;È2‚ü†¼G1”²Q=Ô µC¹¨7„F¢ Ðdt1š ›Ðr´=Œ6¡çЫhÚ>CÇ0Àè3Äl0.ÆÃB±8, “c˱"¬ «Æ°V¬»‰õcϱwEÀ 6wB aAHXLXNØH¨ $4Ú 7 „QÂ'"“¨K´&ºùÄb21‡XH,#Ö/{ˆCÄ7$‰C2'¹I±¤TÒÒFÒnR#é,©›4H#“ÉÚdk²9”, +È…ääÃä3ää!ò[ b@q¤øSâ(RÊjJåå4åe˜2AU£šRݨ¡T5ZB­¡¶R¯Q‡¨4uš9̓IK¥­¢•Óhh÷i¯ètºÝ•N—ÐWÒËéGè—èôw †ƒÇˆg(›gw¯˜L¦Ó‹ÇT071ë˜ç™™oUX*¶*|‘Ê •J•&•*/T©ª¦ªÞª UóUËT©^S}®FU3Sã© Ô–«UªPëSSg©;¨‡ªg¨oT?¤~Yý‰YÃLÃOC¤Q ±_ã¼Æ c³x,!k «†u5Ä&±ÍÙ|v*»˜ý»‹=ª©¡9C3J3W³Ró”f?ã˜qøœtN ç(§—ó~ŠÞï)â)¦4L¹1e\kª–—–X«H«Q«Gë½6®í§¦½E»YûAÇJ'\'GgÎçSÙSݧ §M=:õ®.ªk¥¡»Dw¿n§î˜ž¾^€žLo§Þy½çú}/ýTýmú§õG X³ $Û Î<Å5qo</ÇÛñQC]Ã@C¥a•a—á„‘¹Ñ<£ÕFFŒiÆ\ã$ãmÆmÆ£&&!&KMêMîšRM¹¦)¦;L;LÇÍÌÍ¢ÍÖ™5›=1×2ç›ç›×›ß·`ZxZ,¶¨¶¸eI²äZ¦Yî¶¼n…Z9Y¥XUZ]³F­­%Ö»­»§§¹N“N«žÖgðñ¶É¶©·°åØÛ®¶m¶}agbg·Å®Ã“}º}ý= ‡Ù«Z~s´r:V:ޚΜî?}Åô–é/gXÏÏØ3ã¶Ë)ÄiS›ÓGgg¹sƒóˆ‹‰K‚Ë.—>.›ÆÝȽäJtõq]ázÒõ›³›Âí¨Û¯î6îiî‡ÜŸÌ4Ÿ)žY3sÐÃÈCàQåÑ? Ÿ•0k߬~OCOgµç#/c/‘W­×°·¥wª÷aï>ö>rŸã>ã<7Þ2ÞY_Ì7À·È·ËOÃož_…ßC#ÿdÿzÿѧ€%g‰A[ûøz|!¿Ž?:Ûeö²ÙíAŒ ¹AA‚­‚åÁ­!hÈì­!÷ç˜Î‘Îi…P~èÖÐaæa‹Ã~ '…‡…W†?ŽpˆXÑ1—5wÑÜCsßDúD–DÞ›g1O9¯-J5*>ª.j<Ú7º4º?Æ.fYÌÕXXIlK9.*®6nl¾ßüíó‡ââ ã{˜/È]py¡ÎÂô…§©.,:–@LˆN8”ðA*¨Œ%òw%Ž yÂÂg"/Ñ6шØC\*NòH*Mz’쑼5y$Å3¥,幄'©¼L LÝ›:žšv m2=:½1ƒ’‘qBª!M“¶gêgæfvˬe…²þÅn‹·/•Ék³¬Y- ¶B¦èTZ(×*²geWf¿Í‰Ê9–«ž+Íí̳ÊÛ7œïŸÿíÂá’¶¥†KW-X潬j9²‰Š®Û—Ø(Üxå‡oÊ¿™Ü”´©«Ä¹dÏfÒféæÞ-ž[–ª—æ—n ÙÚ´ ßV´íõöEÛ/—Í(Û»ƒ¶C¹£¿<¸¼e§ÉÎÍ;?T¤TôTúT6îÒݵa×ønÑî{¼ö4ìÕÛ[¼÷ý>ɾÛUUMÕfÕeûIû³÷?®‰ªéø–ûm]­NmqíÇÒý#¶×¹ÔÕÒ=TRÖ+ëGǾþïw- 6 UœÆâ#pDyäé÷ ß÷ :ÚvŒ{¬áÓvg/jBšòšF›Sšû[b[ºOÌ>ÑÖêÞzüGÛœ499â?rýéü§CÏdÏ&žþ¢þË®/~øÕë×Îјѡ—ò—“¿m|¥ýêÀë¯ÛÆÂƾÉx31^ôVûíÁwÜwï£ßOä| (ÿhù±õSЧû“““ÿ˜óüc3-ÛbKGDÿÿÿ ½§“ pHYs  šœtIMEÚ!â›ÈÝ,IDAT8Ëe’_HuÇ?Ïï}ßsŽž3ÍyòË•¶¦‹U2MvQÉÖŠFÔE¬.ŠÑÍÃÅ‚­ÄŠbÑE$DD­‹ËZF5b@QÌ"š:2§›š¦¾ïû{Ÿn.êsõåçû<_ø yî?ô½m÷²ýè·wV™ê@t£R`}Z íÄÐ_£# _=œá_@ÝËý ßw^óRë®·•%6gC-έ(K>ä| $„Éï{¯}ç¬ó³ÏÀ –H3Q5€ ©BàƒÇÄÆáä.@ $p³d!sý#ø~<<+"À¾xÓ ÀM›À0‡ÿêB™\€„Àt‘8K€@zŽB¦@F€˜&S `ËcbãP-`'æÓ€ø™{[”! ‘ eˆDh;¬ÏVŠEX0fKÄ9Ø-0IWfH°·ÀÎ ² 0Qˆ…){`È##x„™FòW<ñ+®ç*x™²<¹$9E[-qWW.(ÎI+6aaš@.Ây™24àóÌ ‘àƒóýxήÎÎ6޶_-ê¿ÿ"bbãþåÏ«p@át~Ñþ,/³€;€mþ¢%îh^  u÷‹f²@µ éÚWópø~<ß5°j>{‘-¨]cöK'XtÀâ÷ò»oÁÔ(€hƒáÏwÿï?ýG %€fI’q^D$.Tʳ?ÇD *°AôÁ,ÀÁÜÁ ü`6„B$ÄÂBB d€r`)¬‚B(†Í°*`/Ô@4ÀQh†“p.ÂU¸=púažÁ(¼ AÈa!ÚˆbŠX#Ž™…ø!ÁH‹$ ɈQ"K‘5H1RŠT UHò=r9‡\Fº‘;È2‚ü†¼G1”²Q=Ô µC¹¨7„F¢ Ðdt1š ›Ðr´=Œ6¡çЫhÚ>CÇ0Àè3Äl0.ÆÃB±8, “c˱"¬ «Æ°V¬»‰õcϱwEÀ 6wB aAHXLXNØH¨ $4Ú 7 „QÂ'"“¨K´&ºùÄb21‡XH,#Ö/{ˆCÄ7$‰C2'¹I±¤TÒÒFÒnR#é,©›4H#“ÉÚdk²9”, +È…ääÃä3ää!ò[ b@q¤øSâ(RÊjJåå4åe˜2AU£šRݨ¡T5ZB­¡¶R¯Q‡¨4uš9̓IK¥­¢•Óhh÷i¯ètºÝ•N—ÐWÒËéGè—èôw †ƒÇˆg(›gw¯˜L¦Ó‹ÇT071ë˜ç™™oUX*¶*|‘Ê •J•&•*/T©ª¦ªÞª UóUËT©^S}®FU3Sã© Ô–«UªPëSSg©;¨‡ªg¨oT?¤~Yý‰YÃLÃOC¤Q ±_ã¼Æ c³x,!k «†u5Ä&±ÍÙ|v*»˜ý»‹=ª©¡9C3J3W³Ró”f?ã˜qøœtN ç(§—ó~ŠÞï)â)¦4L¹1e\kª–—–X«H«Q«Gë½6®í§¦½E»YûAÇJ'\'GgÎçSÙSݧ §M=:õ®.ªk¥¡»Dw¿n§î˜ž¾^€žLo§Þy½çú}/ýTýmú§õG X³ $Û Î<Å5qo</ÇÛñQC]Ã@C¥a•a—á„‘¹Ñ<£ÕFFŒiÆ\ã$ãmÆmÆ£&&!&KMêMîšRM¹¦)¦;L;LÇÍÌÍ¢ÍÖ™5›=1×2ç›ç›×›ß·`ZxZ,¶¨¶¸eI²äZ¦Yî¶¼n…Z9Y¥XUZ]³F­­%Ö»­»§§¹N“N«žÖgðñ¶É¶©·°åØÛ®¶m¶}agbg·Å®Ã“}º}ý= ‡Ù«Z~s´r:V:ޚΜî?}Åô–é/gXÏÏØ3ã¶Ë)ÄiS›ÓGgg¹sƒóˆ‹‰K‚Ë.—>.›ÆÝȽäJtõq]ázÒõ›³›Âí¨Û¯î6îiî‡ÜŸÌ4Ÿ)žY3sÐÃÈCàQåÑ? Ÿ•0k߬~OCOgµç#/c/‘W­×°·¥wª÷aï>ö>rŸã>ã<7Þ2ÞY_Ì7À·È·ËOÃož_…ßC#ÿdÿzÿѧ€%g‰A[ûøz|!¿Ž?:Ûeö²ÙíAŒ ¹AA‚­‚åÁ­!hÈì­!÷ç˜Î‘Îi…P~èÖÐaæa‹Ã~ '…‡…W†?ŽpˆXÑ1—5wÑÜCsßDúD–DÞ›g1O9¯-J5*>ª.j<Ú7º4º?Æ.fYÌÕXXIlK9.*®6nl¾ßüíó‡ââ ã{˜/È]py¡ÎÂô…§©.,:–@LˆN8”ðA*¨Œ%òw%Ž yÂÂg"/Ñ6шØC\*NòH*Mz’쑼5y$Å3¥,幄'©¼L LÝ›:žšv m2=:½1ƒ’‘qBª!M“¶gêgæfvˬe…²þÅn‹·/•Ék³¬Y- ¶B¦èTZ(×*²geWf¿Í‰Ê9–«ž+Íí̳ÊÛ7œïŸÿíÂá’¶¥†KW-X潬j9²‰Š®Û—Ø(Üxå‡oÊ¿™Ü”´©«Ä¹dÏfÒféæÞ-ž[–ª—æ—n ÙÚ´ ßV´íõöEÛ/—Í(Û»ƒ¶C¹£¿<¸¼e§ÉÎÍ;?T¤TôTúT6îÒݵa×ønÑî{¼ö4ìÕÛ[¼÷ý>ɾÛUUMÕfÕeûIû³÷?®‰ªéø–ûm]­NmqíÇÒý#¶×¹ÔÕÒ=TRÖ+ëGǾþïw- 6 UœÆâ#pDyäé÷ ß÷ :ÚvŒ{¬áÓvg/jBšòšF›Sšû[b[ºOÌ>ÑÖêÞzüGÛœ499â?rýéü§CÏdÏ&žþ¢þË®/~øÕë×Îјѡ—ò—“¿m|¥ýêÀë¯ÛÆÂƾÉx31^ôVûíÁwÜwï£ßOä| (ÿhù±õSЧû“““ÿ˜óüc3-ÛbKGDÿÿÿ ½§“ pHYs  šœtIMEÚ 1;ïV·¿§IDAT8Ëu‘ËkÜUÇ?ßsgœ4ÔØøhª‚`µ©ÖG1 RQ‚”îܸp%èBªø”n"‚bРXJ ‹.4V iZð##T;m£µ!4™üæžãbâP­~7÷rîù>ιbwïý†cû†; m;‡oª”ÓAÜàΆ ζZ^«/®þôä£Ãç¸|îs¯ÝÉø{Óý;†¯y¿»Rº¥ð¸Â=È9(rÉt¦Vo¼¾û¡­ûG÷Í1±wíÞÿ#_àÓ©¹›{»¿ìî*•›E&ç å!€€ˆÀƒ(—Lç–VŸßuïÀ«oœéêûÁᲵ‘DŽÀ€ P„‡²G”“4ÿçÊ Ü:&€¯ç~™êî*ݳÖreˆuá: ‚ááS­-,ßUšœ©^Ÿ’ú›E&·™JY[ÃPà!RˆìB ŖޞʖR@_ÎôÈ€dBfó”€NvHfÂ"è2ØTÊî]­ˆR‘’ ³ö j§'BàÖ1‰ddAak…/DIJD… ’D2‘ÌH&L`&L† $Ex,6‹|Ö~_\©¿Pœ‘ $™ýMH`I˜©=Ÿ @¨±Z|õÈÎÁ|ttv´gcåЕ—WTZ'¤õ3rŽÈîje"ܵx¾9ÿö›¯°W> ¹mb©Ñ|by¥ˆ•fFRx{wí%Dúõå¹Z½±€áCíÿÞüô$õwdüÀôðÖ«ÞH¦mW÷nètaµ(ŠM<~;9¿ôáž]C/ñ_¸ãåŸ;÷ÉãÕ«§æã‹Õ#Ÿ}ûÀáÉïoÿ`zS§áÚ·ù_>:;x컓§?Ÿ©yóÝ©ÿ|}æ’~ûwam-/ž®7ž=¾0úìS÷5è»ØíR翚¾P"*Ö¯ IEND®B`‚django-filter-0.11.0/docs/_build/html/_static/default.css0000644000076500000240000000771012436054335024033 0ustar carltonstaff00000000000000/* * default.css_t * ~~~~~~~~~~~~~ * * Sphinx stylesheet -- default theme. * * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ @import url("basic.css"); /* -- page layout ----------------------------------------------------------- */ body { font-family: sans-serif; font-size: 100%; background-color: #11303d; color: #000; margin: 0; padding: 0; } div.document { background-color: #1c4e63; } div.documentwrapper { float: left; width: 100%; } div.bodywrapper { margin: 0 0 0 230px; } div.body { background-color: #ffffff; color: #000000; padding: 0 20px 30px 20px; } div.footer { color: #ffffff; width: 100%; padding: 9px 0 9px 0; text-align: center; font-size: 75%; } div.footer a { color: #ffffff; text-decoration: underline; } div.related { background-color: #133f52; line-height: 30px; color: #ffffff; } div.related a { color: #ffffff; } div.sphinxsidebar { } div.sphinxsidebar h3 { font-family: 'Trebuchet MS', sans-serif; color: #ffffff; font-size: 1.4em; font-weight: normal; margin: 0; padding: 0; } div.sphinxsidebar h3 a { color: #ffffff; } div.sphinxsidebar h4 { font-family: 'Trebuchet MS', sans-serif; color: #ffffff; font-size: 1.3em; font-weight: normal; margin: 5px 0 0 0; padding: 0; } div.sphinxsidebar p { color: #ffffff; } div.sphinxsidebar p.topless { margin: 5px 10px 10px 10px; } div.sphinxsidebar ul { margin: 10px; padding: 0; color: #ffffff; } div.sphinxsidebar a { color: #98dbcc; } div.sphinxsidebar input { border: 1px solid #98dbcc; font-family: sans-serif; font-size: 1em; } /* -- hyperlink styles ------------------------------------------------------ */ a { color: #355f7c; text-decoration: none; } a:visited { color: #355f7c; text-decoration: none; } a:hover { text-decoration: underline; } /* -- body styles ----------------------------------------------------------- */ div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 { font-family: 'Trebuchet MS', sans-serif; background-color: #f2f2f2; font-weight: normal; color: #20435c; border-bottom: 1px solid #ccc; margin: 20px -20px 10px -20px; padding: 3px 0 3px 10px; } div.body h1 { margin-top: 0; font-size: 200%; } div.body h2 { font-size: 160%; } div.body h3 { font-size: 140%; } div.body h4 { font-size: 120%; } div.body h5 { font-size: 110%; } div.body h6 { font-size: 100%; } a.headerlink { color: #c60f0f; font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; } a.headerlink:hover { background-color: #c60f0f; color: white; } div.body p, div.body dd, div.body li { text-align: justify; line-height: 130%; } div.admonition p.admonition-title + p { display: inline; } div.admonition p { margin-bottom: 5px; } div.admonition pre { margin-bottom: 5px; } div.admonition ul, div.admonition ol { margin-bottom: 5px; } div.note { background-color: #eee; border: 1px solid #ccc; } div.seealso { background-color: #ffc; border: 1px solid #ff6; } div.topic { background-color: #eee; } div.warning { background-color: #ffe4e4; border: 1px solid #f66; } p.admonition-title { display: inline; } p.admonition-title:after { content: ":"; } pre { padding: 5px; background-color: #eeffcc; color: #333333; line-height: 120%; border: 1px solid #ac9; border-left: none; border-right: none; } tt { background-color: #ecf0f3; padding: 0 1px 0 1px; font-size: 0.95em; } th { background-color: #ede; } .warning tt { background: #efc2c2; } .note tt { background: #d6d6d6; } .viewcode-back { font-family: sans-serif; } div.viewcode-block:target { background-color: #f4debf; border-top: 1px solid #ac9; border-bottom: 1px solid #ac9; }django-filter-0.11.0/docs/_build/html/_static/doctools.js0000644000076500000240000001503012435161671024054 0ustar carltonstaff00000000000000/* * doctools.js * ~~~~~~~~~~~ * * Sphinx JavaScript utilities for all documentation. * * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /** * select a different prefix for underscore */ $u = _.noConflict(); /** * make the code below compatible with browsers without * an installed firebug like debugger if (!window.console || !console.firebug) { var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"]; window.console = {}; for (var i = 0; i < names.length; ++i) window.console[names[i]] = function() {}; } */ /** * small helper function to urldecode strings */ jQuery.urldecode = function(x) { return decodeURIComponent(x).replace(/\+/g, ' '); }; /** * small helper function to urlencode strings */ jQuery.urlencode = encodeURIComponent; /** * This function returns the parsed url parameters of the * current request. Multiple values per key are supported, * it will always return arrays of strings for the value parts. */ jQuery.getQueryParameters = function(s) { if (typeof s == 'undefined') s = document.location.search; var parts = s.substr(s.indexOf('?') + 1).split('&'); var result = {}; for (var i = 0; i < parts.length; i++) { var tmp = parts[i].split('=', 2); var key = jQuery.urldecode(tmp[0]); var value = jQuery.urldecode(tmp[1]); if (key in result) result[key].push(value); else result[key] = [value]; } return result; }; /** * highlight a given string on a jquery object by wrapping it in * span elements with the given class name. */ jQuery.fn.highlightText = function(text, className) { function highlight(node) { if (node.nodeType == 3) { var val = node.nodeValue; var pos = val.toLowerCase().indexOf(text); if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { var span = document.createElement("span"); span.className = className; span.appendChild(document.createTextNode(val.substr(pos, text.length))); node.parentNode.insertBefore(span, node.parentNode.insertBefore( document.createTextNode(val.substr(pos + text.length)), node.nextSibling)); node.nodeValue = val.substr(0, pos); } } else if (!jQuery(node).is("button, select, textarea")) { jQuery.each(node.childNodes, function() { highlight(this); }); } } return this.each(function() { highlight(this); }); }; /** * Small JavaScript module for the documentation. */ var Documentation = { init : function() { this.fixFirefoxAnchorBug(); this.highlightSearchWords(); this.initIndexTable(); }, /** * i18n support */ TRANSLATIONS : {}, PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, LOCALE : 'unknown', // gettext and ngettext don't access this so that the functions // can safely bound to a different name (_ = Documentation.gettext) gettext : function(string) { var translated = Documentation.TRANSLATIONS[string]; if (typeof translated == 'undefined') return string; return (typeof translated == 'string') ? translated : translated[0]; }, ngettext : function(singular, plural, n) { var translated = Documentation.TRANSLATIONS[singular]; if (typeof translated == 'undefined') return (n == 1) ? singular : plural; return translated[Documentation.PLURALEXPR(n)]; }, addTranslations : function(catalog) { for (var key in catalog.messages) this.TRANSLATIONS[key] = catalog.messages[key]; this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); this.LOCALE = catalog.locale; }, /** * add context elements like header anchor links */ addContextElements : function() { $('div[id] > :header:first').each(function() { $('
    \u00B6'). attr('href', '#' + this.id). attr('title', _('Permalink to this headline')). appendTo(this); }); $('dt[id]').each(function() { $('\u00B6'). attr('href', '#' + this.id). attr('title', _('Permalink to this definition')). appendTo(this); }); }, /** * workaround a firefox stupidity */ fixFirefoxAnchorBug : function() { if (document.location.hash && $.browser.mozilla) window.setTimeout(function() { document.location.href += ''; }, 10); }, /** * highlight the search words provided in the url in the text */ highlightSearchWords : function() { var params = $.getQueryParameters(); var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; if (terms.length) { var body = $('div.body'); if (!body.length) { body = $('body'); } window.setTimeout(function() { $.each(terms, function() { body.highlightText(this.toLowerCase(), 'highlighted'); }); }, 10); $('') .appendTo($('#searchbox')); } }, /** * init the domain index toggle buttons */ initIndexTable : function() { var togglers = $('img.toggler').click(function() { var src = $(this).attr('src'); var idnum = $(this).attr('id').substr(7); $('tr.cg-' + idnum).toggle(); if (src.substr(-9) == 'minus.png') $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); else $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); }).css('display', ''); if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { togglers.click(); } }, /** * helper function to hide the search marks again */ hideSearchWords : function() { $('#searchbox .highlight-link').fadeOut(300); $('span.highlighted').removeClass('highlighted'); }, /** * make the url absolute */ makeURL : function(relativeURL) { return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; }, /** * get the current relative url */ getCurrentURL : function() { var path = document.location.pathname; var parts = path.split(/\//); $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { if (this == '..') parts.pop(); }); var url = parts.join('/'); return path.substring(url.lastIndexOf('/') + 1, path.length - 1); } }; // quick alias for translations _ = Documentation.gettext; $(document).ready(function() { Documentation.init(); }); django-filter-0.11.0/docs/_build/html/_static/down-pressed.png0000644000076500000240000000056012435161671025012 0ustar carltonstaff00000000000000‰PNG  IHDRóÿasRGB®ÎébKGDùC» pHYs × ×B(›xtIMEÚ -vF#ðIDAT8ËÍÒ!OAàïÚJ, ++@ I v¢bÿ@Wñ7F’ HNâ±ú# ‚4¡8Ì6¹4×6Tñ’MvvÞ¼7³»êœûöDs¿‡aóxâ1†U îq‚;<¦ˆÏ E¸Â-f)âºj%ßpˆo4xFà78G…>æ)â-ƒ ž ¡ÂEYm4%7YTk-¾–Q¶a–"NWAo-y†eqÒá¾,)â ÓÒYÓÑú´ptŽÐå½\hóq´Îím˜sÔz¦ìG]ÄNñ‡Òa…‡röçß¶¨s^lã vh\î2Ù%ðâßãŽ0EeRvØIEND®B`‚django-filter-0.11.0/docs/_build/html/_static/down.png0000644000076500000240000000055312435161671023351 0ustar carltonstaff00000000000000‰PNG  IHDRóÿasRGB®ÎébKGDùC» pHYs × ×B(›xtIMEÚ"ÅíU{ëIDAT8ËÍÒ¡NCAÐóÚJ, ++@ ™4>‡¨â/ÐUü’¤^,†~T&Ô3M^^^ÛPÅM6ÙÙ¹sïÌî*¥ôí‰RJ¿‡a)e¼GñÃ*ƒœàñ¹¡èW¸Å<"®«Fò ‡øFgÜã78G…>q ƒ†ÁOI¨p‘«‰:s“õAÕjñ5GÙ†yDœ®ƒ^+y†U:ép_%G§@D|ašÕ­O“£s„Æ(ïy¡M,"â¨Íím˜sÔx:÷£.b§@D|`–V˜åÙŸÛ²”²ÜÆìиÜe²KàÅ¿Ç/êG!‚ ™IEND®B`‚django-filter-0.11.0/docs/_build/html/_static/file.png0000644000076500000240000000061012435161671023313 0ustar carltonstaff00000000000000‰PNG  IHDRóÿabKGDÿÿÿ ½§“ pHYs  šœtIMEÕ  )¶TIDAT8Ë­‘±JÄ@†¿Ir('[ "&xØÙYZ ‚Xø0‚!i|†_@±Ô÷•t§ÓDÄæÏ] ¹#¹Äxÿjv˜ùç› Y–ÐN‡ažE‘i«(ŠÌÄÉ™yž£µ@D¦£&±ˆ`Û6®ë–P¦Zk’$)5%"ôz½Ê.NñA#Aœba‘`Vsø¾_3ñc°,«™àä2m¼Ýñþjó [kŸìlv¹y|!IÕ´ðþyô;ÀðvÈé "Œß®°—a©?ŸAúðÄ7Œ`ô˜ñÇc^énôk?¸²Bg}»TЙ¹D#ÁÑÞ "R¹D1÷£çyüEŽRê*ŽãÝ6MJ©3þK_U«t8F~ÇIEND®B`‚django-filter-0.11.0/docs/_build/html/_static/jquery.js0000644000076500000240000026670512435161671023566 0ustar carltonstaff00000000000000/*! jQuery v1.8.3 jquery.com | jquery.org/license */ (function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
    a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
    t
    ",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
    ",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
    ",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

    ",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
    ","
    "]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
    ").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window);django-filter-0.11.0/docs/_build/html/_static/minus.png0000644000076500000240000000030712435161671023532 0ustar carltonstaff00000000000000‰PNG  IHDR &Îàq pHYs  šœtIME× <®8åtEXtCommentöÌ–¿RIDATÓczô(BÅñãÇáÒpö¿ÿ¨èˆip»‘¹P÷îÝÃc· ¸ |¶IEND®B`‚django-filter-0.11.0/docs/_build/html/_static/pygments.css0000644000076500000240000000762712436054334024263 0ustar carltonstaff00000000000000.highlight .hll { background-color: #ffffcc } .highlight { background: #eeffcc; } .highlight .c { color: #408090; font-style: italic } /* Comment */ .highlight .err { border: 1px solid #FF0000 } /* Error */ .highlight .k { color: #007020; font-weight: bold } /* Keyword */ .highlight .o { color: #666666 } /* Operator */ .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ .highlight .cp { color: #007020 } /* Comment.Preproc */ .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #A00000 } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #FF0000 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .highlight .gi { color: #00A000 } /* Generic.Inserted */ .highlight .go { color: #333333 } /* Generic.Output */ .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ .highlight .gt { color: #0044DD } /* Generic.Traceback */ .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #007020 } /* Keyword.Pseudo */ .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #902000 } /* Keyword.Type */ .highlight .m { color: #208050 } /* Literal.Number */ .highlight .s { color: #4070a0 } /* Literal.String */ .highlight .na { color: #4070a0 } /* Name.Attribute */ .highlight .nb { color: #007020 } /* Name.Builtin */ .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ .highlight .no { color: #60add5 } /* Name.Constant */ .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ .highlight .ne { color: #007020 } /* Name.Exception */ .highlight .nf { color: #06287e } /* Name.Function */ .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #bb60d5 } /* Name.Variable */ .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #208050 } /* Literal.Number.Bin */ .highlight .mf { color: #208050 } /* Literal.Number.Float */ .highlight .mh { color: #208050 } /* Literal.Number.Hex */ .highlight .mi { color: #208050 } /* Literal.Number.Integer */ .highlight .mo { color: #208050 } /* Literal.Number.Oct */ .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ .highlight .sc { color: #4070a0 } /* Literal.String.Char */ .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ .highlight .s2 { color: #4070a0 } /* Literal.String.Double */ .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ .highlight .sx { color: #c65d09 } /* Literal.String.Other */ .highlight .sr { color: #235388 } /* Literal.String.Regex */ .highlight .s1 { color: #4070a0 } /* Literal.String.Single */ .highlight .ss { color: #517918 } /* Literal.String.Symbol */ .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */django-filter-0.11.0/docs/_build/html/_static/searchtools.js0000644000076500000240000004270212436054335024561 0ustar carltonstaff00000000000000/* * searchtools.js_t * ~~~~~~~~~~~~~~~~ * * Sphinx JavaScript utilties for the full-text search. * * :copyright: Copyright 2007-2014 by the Sphinx team, see AUTHORS. * :license: BSD, see LICENSE for details. * */ /** * Porter Stemmer */ var Stemmer = function() { var step2list = { ational: 'ate', tional: 'tion', enci: 'ence', anci: 'ance', izer: 'ize', bli: 'ble', alli: 'al', entli: 'ent', eli: 'e', ousli: 'ous', ization: 'ize', ation: 'ate', ator: 'ate', alism: 'al', iveness: 'ive', fulness: 'ful', ousness: 'ous', aliti: 'al', iviti: 'ive', biliti: 'ble', logi: 'log' }; var step3list = { icate: 'ic', ative: '', alize: 'al', iciti: 'ic', ical: 'ic', ful: '', ness: '' }; var c = "[^aeiou]"; // consonant var v = "[aeiouy]"; // vowel var C = c + "[^aeiouy]*"; // consonant sequence var V = v + "[aeiou]*"; // vowel sequence var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 var s_v = "^(" + C + ")?" + v; // vowel in stem this.stemWord = function (w) { var stem; var suffix; var firstch; var origword = w; if (w.length < 3) return w; var re; var re2; var re3; var re4; firstch = w.substr(0,1); if (firstch == "y") w = firstch.toUpperCase() + w.substr(1); // Step 1a re = /^(.+?)(ss|i)es$/; re2 = /^(.+?)([^s])s$/; if (re.test(w)) w = w.replace(re,"$1$2"); else if (re2.test(w)) w = w.replace(re2,"$1$2"); // Step 1b re = /^(.+?)eed$/; re2 = /^(.+?)(ed|ing)$/; if (re.test(w)) { var fp = re.exec(w); re = new RegExp(mgr0); if (re.test(fp[1])) { re = /.$/; w = w.replace(re,""); } } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1]; re2 = new RegExp(s_v); if (re2.test(stem)) { w = stem; re2 = /(at|bl|iz)$/; re3 = new RegExp("([^aeiouylsz])\\1$"); re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re2.test(w)) w = w + "e"; else if (re3.test(w)) { re = /.$/; w = w.replace(re,""); } else if (re4.test(w)) w = w + "e"; } } // Step 1c re = /^(.+?)y$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(s_v); if (re.test(stem)) w = stem + "i"; } // Step 2 re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step2list[suffix]; } // Step 3 re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; suffix = fp[2]; re = new RegExp(mgr0); if (re.test(stem)) w = stem + step3list[suffix]; } // Step 4 re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; re2 = /^(.+?)(s|t)(ion)$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); if (re.test(stem)) w = stem; } else if (re2.test(w)) { var fp = re2.exec(w); stem = fp[1] + fp[2]; re2 = new RegExp(mgr1); if (re2.test(stem)) w = stem; } // Step 5 re = /^(.+?)e$/; if (re.test(w)) { var fp = re.exec(w); stem = fp[1]; re = new RegExp(mgr1); re2 = new RegExp(meq1); re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) w = stem; } re = /ll$/; re2 = new RegExp(mgr1); if (re.test(w) && re2.test(w)) { re = /.$/; w = w.replace(re,""); } // and turn initial Y back to y if (firstch == "y") w = firstch.toLowerCase() + w.substr(1); return w; } } /** * Simple result scoring code. */ var Scorer = { // Implement the following function to further tweak the score for each result // The function takes a result array [filename, title, anchor, descr, score] // and returns the new score. /* score: function(result) { return result[4]; }, */ // query matches the full name of an object objNameMatch: 11, // or matches in the last dotted part of the object name objPartialMatch: 6, // Additive scores depending on the priority of the object objPrio: {0: 15, // used to be importantResults 1: 5, // used to be objectResults 2: -5}, // used to be unimportantResults // Used when the priority is not in the mapping. objPrioDefault: 0, // query found in title title: 15, // query found in terms term: 5 }; /** * Search Module */ var Search = { _index : null, _queued_query : null, _pulse_status : -1, init : function() { var params = $.getQueryParameters(); if (params.q) { var query = params.q[0]; $('input[name="q"]')[0].value = query; this.performSearch(query); } }, loadIndex : function(url) { $.ajax({type: "GET", url: url, data: null, dataType: "script", cache: true, complete: function(jqxhr, textstatus) { if (textstatus != "success") { document.getElementById("searchindexloader").src = url; } }}); }, setIndex : function(index) { var q; this._index = index; if ((q = this._queued_query) !== null) { this._queued_query = null; Search.query(q); } }, hasIndex : function() { return this._index !== null; }, deferQuery : function(query) { this._queued_query = query; }, stopPulse : function() { this._pulse_status = 0; }, startPulse : function() { if (this._pulse_status >= 0) return; function pulse() { var i; Search._pulse_status = (Search._pulse_status + 1) % 4; var dotString = ''; for (i = 0; i < Search._pulse_status; i++) dotString += '.'; Search.dots.text(dotString); if (Search._pulse_status > -1) window.setTimeout(pulse, 500); } pulse(); }, /** * perform a search for something (or wait until index is loaded) */ performSearch : function(query) { // create the required interface elements this.out = $('#search-results'); this.title = $('

    ' + _('Searching') + '

    ').appendTo(this.out); this.dots = $('').appendTo(this.title); this.status = $('

    ').appendTo(this.out); this.output = $('
    '); } // Prettify the comment rating. comment.pretty_rating = comment.rating + ' point' + (comment.rating == 1 ? '' : 's'); // Make a class (for displaying not yet moderated comments differently) comment.css_class = comment.displayed ? '' : ' moderate'; // Create a div for this comment. var context = $.extend({}, opts, comment); var div = $(renderTemplate(commentTemplate, context)); // If the user has voted on this comment, highlight the correct arrow. if (comment.vote) { var direction = (comment.vote == 1) ? 'u' : 'd'; div.find('#' + direction + 'v' + comment.id).hide(); div.find('#' + direction + 'u' + comment.id).show(); } if (opts.moderator || comment.text != '[deleted]') { div.find('a.reply').show(); if (comment.proposal_diff) div.find('#sp' + comment.id).show(); if (opts.moderator && !comment.displayed) div.find('#cm' + comment.id).show(); if (opts.moderator || (opts.username == comment.username)) div.find('#dc' + comment.id).show(); } return div; } /** * A simple template renderer. Placeholders such as <%id%> are replaced * by context['id'] with items being escaped. Placeholders such as <#id#> * are not escaped. */ function renderTemplate(template, context) { var esc = $(document.createElement('div')); function handle(ph, escape) { var cur = context; $.each(ph.split('.'), function() { cur = cur[this]; }); return escape ? esc.text(cur || "").html() : cur; } return template.replace(/<([%#])([\w\.]*)\1>/g, function() { return handle(arguments[2], arguments[1] == '%' ? true : false); }); } /** Flash an error message briefly. */ function showError(message) { $(document.createElement('div')).attr({'class': 'popup-error'}) .append($(document.createElement('div')) .attr({'class': 'error-message'}).text(message)) .appendTo('body') .fadeIn("slow") .delay(2000) .fadeOut("slow"); } /** Add a link the user uses to open the comments popup. */ $.fn.comment = function() { return this.each(function() { var id = $(this).attr('id').substring(1); var count = COMMENT_METADATA[id]; var title = count + ' comment' + (count == 1 ? '' : 's'); var image = count > 0 ? opts.commentBrightImage : opts.commentImage; var addcls = count == 0 ? ' nocomment' : ''; $(this) .append( $(document.createElement('a')).attr({ href: '#', 'class': 'sphinx-comment-open' + addcls, id: 'ao' + id }) .append($(document.createElement('img')).attr({ src: image, alt: 'comment', title: title })) .click(function(event) { event.preventDefault(); show($(this).attr('id').substring(2)); }) ) .append( $(document.createElement('a')).attr({ href: '#', 'class': 'sphinx-comment-close hidden', id: 'ah' + id }) .append($(document.createElement('img')).attr({ src: opts.closeCommentImage, alt: 'close', title: 'close' })) .click(function(event) { event.preventDefault(); hide($(this).attr('id').substring(2)); }) ); }); }; var opts = { processVoteURL: '/_process_vote', addCommentURL: '/_add_comment', getCommentsURL: '/_get_comments', acceptCommentURL: '/_accept_comment', deleteCommentURL: '/_delete_comment', commentImage: '/static/_static/comment.png', closeCommentImage: '/static/_static/comment-close.png', loadingImage: '/static/_static/ajax-loader.gif', commentBrightImage: '/static/_static/comment-bright.png', upArrow: '/static/_static/up.png', downArrow: '/static/_static/down.png', upArrowPressed: '/static/_static/up-pressed.png', downArrowPressed: '/static/_static/down-pressed.png', voting: false, moderator: false }; if (typeof COMMENT_OPTIONS != "undefined") { opts = jQuery.extend(opts, COMMENT_OPTIONS); } var popupTemplate = '\
    \

    \ Sort by:\ best rated\ newest\ oldest\

    \
    Comments
    \
    \ loading comments...
    \
      \
      \

      Add a comment\ (markup):

      \
      \ reStructured text markup: *emph*, **strong**, \ ``code``, \ code blocks: :: and an indented block after blank line
      \
      \ \

      \ \ Propose a change ▹\ \ \ Propose a change ▿\ \

      \ \ \ \ \ \
      \
      '; var commentTemplate = '\
      \
      \
      \ \ \ \ \ \ \
      \
      \ \ \ \ \ \ \
      \
      \
      \

      \ <%username%>\ <%pretty_rating%>\ <%time.delta%>\

      \
      <#text#>
      \

      \ \ reply ▿\ proposal ▹\ proposal ▿\ \ \

      \
      \
      <#proposal_diff#>\
              
      \
        \
        \
        \
        \ '; var replyTemplate = '\
      • \
        \
        \ \ \ \ \ \ \
        \
      • '; $(document).ready(function() { init(); }); })(jQuery); $(document).ready(function() { // add comment anchors for all paragraphs that are commentable $('.sphinx-has-comment').comment(); // highlight search words in search results $("div.context").each(function() { var params = $.getQueryParameters(); var terms = (params.q) ? params.q[0].split(/\s+/) : []; var result = $(this); $.each(terms, function() { result.highlightText(this.toLowerCase(), 'highlighted'); }); }); // directly open comment window if requested var anchor = document.location.hash; if (anchor.substring(0, 9) == '#comment-') { $('#ao' + anchor.substring(9)).click(); document.location.hash = '#s' + anchor.substring(9); } }); django-filter-0.11.0/docs/_build/html/genindex.html0000644000076500000240000000532112436054334022731 0ustar carltonstaff00000000000000 Index — django-filter 0.9.0 documentation

        Index

        django-filter-0.11.0/docs/_build/html/index.html0000644000076500000240000001035412436054334022241 0ustar carltonstaff00000000000000 django-filter — django-filter 0.9.0 documentation

        django-filter¶

        Django-filter is a generic, reusable application to alleviate writing some of the more mundane bits of view code. Specifically, it allows users to filter down a queryset based on a model’s fields, displaying the form to let them do this.

        Contents:

        Next topic

        Installing django-filter

        This Page

        django-filter-0.11.0/docs/_build/html/install.html0000644000076500000240000001040212436054334022572 0ustar carltonstaff00000000000000 Installing django-filter — django-filter 0.9.0 documentation

        Installing django-filter¶

        To install, simply place the django_filters directory somewhere on your PYTHONPATH, and then add 'django_filters' to your INSTALLED_APPS.

        Previous topic

        django-filter

        Next topic

        Using django-filter

        This Page

        django-filter-0.11.0/docs/_build/html/objects.inv0000644000076500000240000000032312436054335022407 0ustar carltonstaff00000000000000# Sphinx inventory version 2 # Project: django-filter # Version: 0.9.0 # The remainder of this file is compressed using zlib. xÚËÍOÉÌKI­P(.I±ÊILJÍQÐ5T(¨ÔÍ…Jèe”äæ(+øæ§”æ¤*x‚„¸ÒSó°h‚‰Bu@”§&%g *„ˆA•C$¦§rßæ1django-filter-0.11.0/docs/_build/html/ref/0000755000076500000240000000000012563340512021012 5ustar carltonstaff00000000000000django-filter-0.11.0/docs/_build/html/ref/filters.html0000644000076500000240000005521712436054334023365 0ustar carltonstaff00000000000000 Filter Reference — django-filter 0.9.0 documentation

        Filter Reference¶

        This is a reference document with a list of the filters and their arguments.

        Filters¶

        CharFilter¶

        This filter does simple character matches, used with CharField and TextField by default.

        BooleanFilter¶

        This filter matches a boolean, either True or False, used with BooleanField and NullBooleanField by default.

        ChoiceFilter¶

        This filter matches an item of any type by choices, used with any field that has choices.

        TypedChoiceFilter¶

        The same as ChoiceFilter with the added possibility to convert value to match against. This could be done by using coerce parameter. An example use-case is limiting boolean choices to match against so only some predefined strings could be used as input of a boolean filter:

        import django_filters
        from distutils.util import strtobool
        
        BOOLEAN_CHOICES = (('false', 'False'), ('true', 'True'),)
        
        class YourFilterSet(django_filters.FilterSet):
            ...
            flag = django_filters.TypedChoiceFilter(choices=BOOLEAN_CHOICES,
                                                    coerce=strtobool)
        

        MultipleChoiceFilter¶

        The same as ChoiceFilter except the user can select multiple items and it selects the OR of all the choices.

        Advanced Use: Depending on your application logic, when all or no choices are selected, filtering may be a noop. In this case you may wish to avoid the filtering overhead, particularly of the distinct call.

        Set always_filter to False after instantiation to enable the default is_noop test.

        Override is_noop if you require a different test for your application.

        DateFilter¶

        Matches on a date. Used with DateField by default.

        DateTimeFilter¶

        Matches on a date and time. Used with DateTimeField by default.

        TimeFilter¶

        Matches on a time. Used with TimeField by default.

        ModelChoiceFilter¶

        Similar to a ChoiceFilter except it works with related models, used for ForeignKey by default.

        ModelMultipleChoiceFilter¶

        Similar to a MultipleChoiceFilter except it works with related models, used for ManyToManyField by default.

        NumberFilter¶

        Filters based on a numerical value, used with IntegerField, FloatField, and DecimalField by default.

        RangeFilter¶

        Filters where a value is between two numerical values, or greater than a minimum or less than a maximum where only one limit value is provided.

        class F(FilterSet):
            """Filter for Books by Price"""
            price = RangeFilter()
        
            class Meta:
                model = Book
                fields = ['price']
        
        qs = Book.objects.all().order_by('title')
        
        # Range: Books between 5€ and 15€
        f = F({'price_0': '5', 'price_1': '15'}, queryset=qs)
        
        # Min-Only: Books costing more the 11€
        f = F({'price_0': '11'}, queryset=qs)
        
        # Max-Only: Books costing less than 19€
        f = F({'price_1': '19'}, queryset=qs)
        

        DateRangeFilter¶

        Filter similar to the admin changelist date one, it has a number of common selections for working with date fields.

        AllValuesFilter¶

        This is a ChoiceFilter whose choices are the current values in the database. So if in the DB for the given field you have values of 5, 7, and 9 each of those is present as an option. This is similar to the default behavior of the admin.

        MethodFilter¶

        This is a Filter that will allow you to run a method that exists on the filter set that this filter is a property of. Set the action to a string that will map to a method on the filter set class.

        Core Arguments¶

        name¶

        The name of the field this filter is supposed to filter on, if this is not provided it automatically becomes the filter’s name on the FilterSet.

        label¶

        The label as it will apear in the HTML, analogous to a form field’s label argument.

        widget¶

        The django.form Widget class which will represent the Filter. In addition to the widgets that are included with Django that you can use there are additional ones that django-filter provides which may be useful:

        • django_filters.widgets.LinkWidget – this displays the options in a mannner similar to the way the Django Admin does, as a series of links. The link for the selected option will have class="selected".

        action¶

        An optional callable that tells the filter how to handle the queryset. It recieves a QuerySet and the value to filter on and should return a Queryset that is filtered appropriately.

        lookup_type¶

        The type of lookup that should be performed using the [Django ORM](https://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookups “Django’s ORM Lookups”). All the normal options are allowed, and should be provided as a string. You can also provide either None or a list or a tuple. If None is provided, then the user can select the lookup type from all the ones available in the Django ORM. If a list or tuple is provided, then the user can select from those options.

        distinct¶

        A boolean value that specifies whether the Filter will use distinct on the queryset. This option can be used to eliminate duplicate results when using filters that span related models. Defaults to False.

        exclude¶

        A boolean value that specifies whether the Filter should use filter or exclude on the queryset. Defaults to False.

        **kwargs¶

        Any extra keyword arguments will be provided to the accompanying form Field. This can be used to provide arguments like choices or queryset.

        django-filter-0.11.0/docs/_build/html/ref/widgets.html0000644000076500000240000001273212436054334023356 0ustar carltonstaff00000000000000 Widget Reference — django-filter 0.9.0 documentation

        Widget Reference¶

        This is a reference document with a list of the provided widgets and their arguments.

        LinkWidget¶

        This widget renders each option as a link, instead of an actual <input>. It has one method that you can overide for additional customizability. option_string() should return a string with 3 Python keyword argument placeholders:

        1. attrs: This is a string with all the attributes that will be on the final <a> tag.
        2. query_string: This is the query string for use in the href option on the <a> elemeent.
        3. label: This is the text to be displayed to the user.

        Table Of Contents

        Previous topic

        Filter Reference

        Next topic

        Running the django-filter tests

        This Page

        django-filter-0.11.0/docs/_build/html/search.html0000644000076500000240000000621112436054334022374 0ustar carltonstaff00000000000000 Search — django-filter 0.9.0 documentation

        Search

        Please activate JavaScript to enable the search functionality.

        From here you can search these documents. Enter your search words into the box below and click "search". Note that the search function will automatically search for all of the words. Pages containing fewer words won't appear in the result list.

        django-filter-0.11.0/docs/_build/html/searchindex.js0000644000076500000240000001167612436054335023110 0ustar carltonstaff00000000000000Search.setIndex({envversion:42,terms:{all:[5,2,1,3],code:[5,0,1],forget:5,queri:[5,3],signific:5,follow:1,whose:2,depend:[],those:[5,2],filterset_class:5,query_str:3,get_order_bi:5,sourc:1,string:[5,2,3],fals:[5,2],price__gt:5,util:2,veri:5,exact:5,ref:2,overid:3,list:[5,2,3],last_nam:5,iter:5,item:[5,2],listview:5,cost:2,pass:5,what:5,access:5,"new":[5,1],method:[],widget:[],abov:5,gener:[],never:5,here:5,let:[5,0],path:5,becom:2,valu:[5,2],price_1:2,price_0:2,convert:2,base:[5,0,2],overrid:[],extra:[5,2],app:5,deprec:5,"boolean":2,instal:[],txt:1,select:[5,2],from:[5,2],would:5,two:2,live:5,overhead:2,type:[5,2],tell:2,more:[2,0],sort:5,relat:[5,2],flag:2,obj:5,compani:5,hold:5,easiest:1,must:5,none:2,work:[5,2],dev:2,tag:3,can:[5,2,1,3],empty_label:5,def:5,filter_class:5,control:5,loosen:5,indic:5,manytomanyfield:2,minimum:2,want:5,multipl:[5,2],first_nam:5,mundan:0,object_list:5,write:[5,0],how:2,place:4,simpl:[5,2],updat:5,map:2,product:5,max:2,clone:1,after:2,charfield:[5,2],mai:[5,2],strtobool:2,github:1,virutalenv:1,apear:2,"switch":1,allow:[5,0,2],enter:5,callabl:2,lambda:5,over:5,becaus:5,still:5,paramet:[5,2],render:3,complex:5,linkwidget:[],therefor:5,them:[5,0],lastli:5,"return":[5,2,3],greater:2,thei:5,handl:2,initi:5,number:[5,2],filter_overrid:5,instead:3,now:5,choic:2,somewher:4,achiev:5,average_r:5,each:[2,3],found:5,mean:5,runtest:1,expect:5,our:5,out:1,variabl:5,content:[5,0],userfilt:5,modelform:5,urlpattern:5,advanc:2,differ:2,orm:[5,2],dictionari:5,reusabl:0,could:2,datetimefield:2,pagin:5,isn:5,as_p:5,onto:5,first:5,rang:2,directli:5,option_str:3,placehold:3,date:2,legaci:5,done:2,timefield:2,installed_app:4,predefin:2,given:2,script:1,wrapper:1,max_length:5,"final":3,store:5,inner:5,option:[],relationship:5,always_filt:2,specifi:[5,2],accompani:2,textfield:[5,2],than:[5,2],kind:5,django_filt:[5,2,4],keyword:[5,2,3],provid:[5,2,3],charact:2,seri:2,sai:5,runner:1,changelist:2,queryset:[5,0,2],ani:[5,2],object_filt:5,have:[5,2,1],tabl:5,need:5,min:2,self:5,note:5,also:[5,2],exampl:[5,2],take:5,which:[5,2],thi:[5,0,3,2],integerfield:2,normal:[5,2],usernam:5,price:[5,2],object:[5,2],why:5,allevi:0,doc:2,request:5,doe:2,declar:5,databas:2,show:5,text:[5,3],syntax:5,particularli:2,current:2,onli:2,coerc:2,locat:1,activ:1,should:[2,3],manufactur:5,suppos:2,decimalfield:[5,2],boolean_choic:2,requir:[2,1],enabl:2,is_noop:2,whether:[5,2],common:[5,2],contain:5,where:[2,1],view:[],set:[],elimin:2,maximum:2,see:5,result:[5,2],arg:5,price__lt:5,analog:2,wonder:5,pattern:5,between:2,my_app:5,"import":[5,2],modeladmin:5,attribut:[5,3],extend:5,numer:2,addit:[5,2,3],last:5,admin:[5,2],similar:[5,2],against:2,context:5,logic:2,com:[2,1],simpli:4,instanti:2,foobar:5,mannner:2,assum:1,duplic:[5,2],reciev:2,quit:5,addition:5,empti:5,search:5,floatfield:2,present:2,"case":[5,2],properti:2,behavior:[5,2],as_view:5,endblock:5,customiz:3,itself:5,href:3,myapp:5,"__init__":5,perform:2,same:[5,2],python:[1,3],"_filter":5,html:[5,2],document:[2,3],filterset:[],http:[2,1],order_valu:5,effect:5,render_to_respons:5,nullbooleanfield:2,user:[5,0,3,2],distutil:2,appropri:2,yourfilterset:2,elem:3,without:5,command:1,endfor:5,model:[],datefield:[5,2],just:5,less:[5,2],display_nam:5,except:2,icontain:5,add:[5,4],input:[5,2,3],match:2,bin:1,applic:[2,0],format:5,field_nam:5,alex:1,bit:0,like:[5,2],specif:0,arbitrari:5,manufacturer__countri:5,order_by_field:5,api:5,either:[5,2],page:5,some:[2,0],djangoproject:2,avoid:2,subclass:5,noop:2,foo:5,refer:[],run:[],release_d:5,usag:5,although:5,"super":5,actual:3,manag:5,filterview:5,product_list:5,block:5,pythonpath:4,within:1,automat:2,down:[5,0],contrib:5,bool:5,your:[5,2,4],git:1,span:2,wai:[5,2,1],submit:5,custom:[],avail:[2,1],start:5,includ:[5,2],call:[5,2],"function":5,form:[],tupl:[5,2],link:[2,3],"true":[5,2],attr:3,possibl:[5,2],"default":[5,2],wish:2,displai:[5,0,3,2],limit:2,foreignkei:[5,2],booleanfield:2,creat:[5,1],doesn:5,repres:2,exist:2,pip:1,check:1,probabl:5,titl:2,when:[5,2],invalid:5,field:[5,0,2],book:2,lookup:[5,2],test:[],you:[5,2,1,3],star:5,sequenc:5,"class":[5,2],directori:[1,4],descript:5,productfilt:5,ignor:5,time:2},objtypes:{},objnames:{},filenames:["index","tests","ref/filters","ref/widgets","install","usage"],titles:["django-filter","Running the django-filter tests","Filter Reference","Widget Reference","Installing django-filter","Using django-filter"],objects:{},titleterms:{overrid:5,set:1,methodfilt:2,allvaluesfilt:2,datetimefilt:2,argument:2,templat:5,datefilt:2,kwarg:2,conf:5,rangefilt:2,instal:[1,4],label:2,choicefilt:2,virtualenv:1,depend:1,lookup_typ:2,distinct:2,custom:5,strict:5,other:5,order_bi:5,modelchoicefilt:2,suit:1,test:1,django:[5,0,1,4],method:5,refer:[2,3],core:2,non:5,run:1,option:5,form:5,get:1,multiplechoicefilt:2,gener:5,copi:1,timefilt:2,get_ordering_field:5,typedchoicefilt:2,modelmultiplechoicefilt:2,linkwidget:3,name:2,url:5,widget:[2,3],exclud:2,filter:[5,0,1,2,4],meta:5,booleanfilt:2,numberfilt:2,charfilt:2,action:2,daterangefilt:2,model:5,filterset:5,order:5,view:5}})django-filter-0.11.0/docs/_build/html/tests.html0000644000076500000240000001406012436054334022272 0ustar carltonstaff00000000000000 Running the django-filter tests — django-filter 0.9.0 documentation

        Running the django-filter tests¶

        The easiest way to run the django-filter tests is to check out the source code into a virtualenv, where you can install the test dependencies. django-filter uses a custom test runner to locate all of the tests, so a wrapper script is available to set up and run the test suite.

        Note

        The following assumes you have virtualenv and git installed.

        Set up a virtualenv for the test suite¶

        Run the following to create a new virtualenv to run the test suite in:

        virtualenv django-filter-tests
        cd django-filter-tests
        . bin/activate
        

        Get a copy of django-filter¶

        Get the django-filter source code using the following command:

        git clone https://github.com/alex/django-filter.git
        

        Switch to the django-filter directory:

        cd django-filter
        

        Install the test dependencies¶

        Run the following to install the test dependencies within the virutalenv:

        pip install -r requirements/test.txt
        

        Run the django-filter tests:

        python runtests.py
        

        Table Of Contents

        Previous topic

        Widget Reference

        This Page

        django-filter-0.11.0/docs/_build/html/usage.html0000644000076500000240000007615712436054334022253 0ustar carltonstaff00000000000000 Using django-filter — django-filter 0.9.0 documentation

        Using django-filter¶

        Django-filter provides a simple way to filter down a queryset based on parameters a user provides. Say we have a Product model and we want to let our users filter which products they see on a list page.

        The model¶

        Let’s start with our model:

        from django.db import models
        
        class Product(models.Model):
            name = models.CharField(max_length=255)
            price = models.DecimalField()
            description = models.TextField()
            release_date = models.DateField()
            manufacturer = models.ForeignKey(Manufacturer)
        

        The filter¶

        We have a number of fields and we want to let our users filter based on the price or the release_date. We create a FilterSet for this:

        import django_filters
        
        class ProductFilter(django_filters.FilterSet):
            class Meta:
                model = Product
                fields = ['price', 'release_date']
        

        As you can see this uses a very similar API to Django’s ModelForm. Just like with a ModelForm we can also override filters, or add new ones using a declarative syntax:

        import django_filters
        
        class ProductFilter(django_filters.FilterSet):
            price = django_filters.NumberFilter(lookup_type='lt')
            class Meta:
                model = Product
                fields = ['price', 'release_date']
        

        Filters take a lookup_type argument which specifies what lookup type to use with Django’s ORM. So here when a user entered a price it would show all Products with a price less than that.

        It’s quite common to forget to set lookup type for `CharField`s/`TextField`s and wonder why search for “foo” doesn’t return result for “foobar”. It’s because default lookup type is exact text, but you probably want `icontains` lookup field.

        The FilterSet Meta class fields can additionally be set using a Dictionary to specify multiple lookup_type filters without significant code duplication:

        import django_filters
        
        class ProductFilter(django_filters.FilterSet):
            class Meta:
                model = Product
                fields = {'price': ['lt', 'gt'],
                          'release_date': ['exact'],
                         }
        

        The above would generate ‘price__lt’, ‘price__gt’ and ‘release_date’ filters. The filter lookup type keyword ‘exact’ is the default and therefore never added to a filter name.

        Items in the fields sequence in the Meta class may include “relationship paths” using Django’s __ syntax to filter on fields on a related model:

        class ProductFilter(django_filters.FilterSet):
            class Meta:
                model = Product
                fields = ['manufacturer__country']
        

        Filters also take any arbitrary keyword arguments which get passed onto the django.forms.Field initializer. These extra keyword arguments get stored in Filter.extra, so it’s possible to override the initializer of a FilterSet to add extra ones:

        class ProductFilter(django_filters.FilterSet):
            class Meta:
                model = Product
                fields = ['manufacturer']
        
            def __init__(self, *args, **kwargs):
                super(ProductFilter, self).__init__(*args, **kwargs)
                self.filters['manufacturer'].extra.update(
                    {'empty_label': 'All Manufacturers'})
        

        Like django.contrib.admin.ModelAdmin, it is possible to override default filters for all the models fields of the same kind using filter_overrides:

        class ProductFilter(django_filters.FilterSet):
            filter_overrides = {
                models.CharField: {
                    'filter_class': django_filters.CharFilter,
                    'extra': lambda f: {
                        'lookup_type': 'icontains',
                    }
                }
            }
        
            class Meta:
                model = Product
                fields = ['name']
        

        The view¶

        Now we need to write a view:

        def product_list(request):
            f = ProductFilter(request.GET, queryset=Product.objects.all())
            return render_to_response('my_app/template.html', {'filter': f})
        

        If a queryset argument isn’t provided then all the items in the default manager of the model will be used.

        If you want to access the filtered objects in your views, for example if you want to paginate them, you can do that. They are in f.qs

        The URL conf¶

        We need a URL pattern to call the view:

        url(r'^list$', views.product_list)
        

        The template¶

        And lastly we need a template:

        {% extends "base.html" %}
        
        {% block content %}
            <form action="" method="get">
                {{ filter.form.as_p }}
                <input type="submit" />
            </form>
            {% for obj in filter %}
                {{ obj.name }} - ${{ obj.price }}<br />
            {% endfor %}
        {% endblock %}
        

        And that’s all there is to it! The form attribute contains a normal Django form, and when we iterate over the FilterSet we get the objects in the resulting queryset.

        Other Meta options¶

        Ordering using order_by¶

        You can allow the user to control ordering by providing the order_by argument in the Filter’s Meta class. order_by can be either a list or tuple of field names, in which case those are the options, or it can be a bool which, if True, indicates that all fields that the user can filter on can also be sorted on. An example or ordering using a list:

        import django_filters
        
        class ProductFilter(django_filters.FilterSet):
            price = django_filters.NumberFilter(lookup_type='lt')
            class Meta:
                model = Product
                fields = ['price', 'release_date']
                order_by = ['price']
        

        If you want to control the display of items in order_by, you can set it to a list or tuple of 2-tuples in the format (field_name, display_name). This lets you override the displayed names for your ordering fields:

        order_by = (
            ('name', 'Company Name'),
            ('average_rating', 'Stars'),
        )
        

        Note that the default query parameter name used for ordering is o. You can override this by setting an order_by_field attribute on the FilterSet class to the string value you would like to use.

        Custom Forms using form¶

        The inner Meta class also takes an optional form argument. This is a form class from which FilterSet.form will subclass. This works similar to the form option on a ModelAdmin.

        Non-Meta options¶

        Note that these options do not go in the Meta class, they are specified directly in your FilterSet class.

        strict¶

        The strict option controls whether results are returned when an invalid value is specified by the user for any filter field. By default, strict is set to True meaning that an empty queryset is returned if any field contains an invalid value. You can loosen this behavior by setting strict to False which will effectively ignore a filter field if its value is invalid.

        Overriding FilterSet methods¶

        get_ordering_field()¶

        If you want to use a custom widget, or in any other way override the ordering field you can override the get_ordering_field() method on a FilterSet. This method just needs to return a Form Field.

        Ordering on multiple fields, or other complex orderings can be achieved by overriding the Filterset.get_order_by() method. This is passed the selected order_by value, and is expected to return an iterable of values to pass to QuerySet.order_by. For example, to sort a User table by last name, then first name:

        class UserFilter(django_filters.FilterSet):
            class Meta:
                order_by = (
                    ('username', 'Username'),
                    ('last_name', 'Last Name')
                )
        
            def get_order_by(self, order_value):
                if order_value == 'last_name':
                    return ['last_name', 'first_name']
                return super(UserFilter, self).get_order_by(order_value)
        

        Generic View¶

        In addition to the above usage there is also a class-based generic view included in django-filter, which lives at django_filters.views.FilterView. You must provide either a model or filterset_class argument, similar to ListView in Django itself:

        # urls.py
        from django.conf.urls import patterns, url
        from django_filters.views import FilterView
        from myapp.models import Product
        
        urlpatterns = patterns('',
            (r'^list/$', FilterView.as_view(model=Product)),
        )
        

        You must provide a template at <app>/<model>_filter.html which gets the context parameter filter. Additionally, the context will contain object_list which holds the filtered queryset.

        A legacy functional generic view is still included in django-filter, although its use is deprecated. It can be found at django_filters.views.object_filter. You must provide the same arguments to it as the class based view:

        # urls.py
        from django.conf.urls import patterns, url
        from myapp.models import Product
        
        urlpatterns = patterns('',
            (r'^list/$', 'django_filters.views.object_filter', {'model': Product}),
        )
        

        The needed template and its context variables will also be the same as the class-based view above.

        django-filter-0.11.0/docs/conf.py0000644000076500000240000001722312563340337017345 0ustar carltonstaff00000000000000# -*- coding: utf-8 -*- # # django-filter documentation build configuration file, created by # sphinx-quickstart on Mon Sep 17 11:25:20 2012. # # This file is execfile()d with the current directory set to its containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys, os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.txt' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'django-filter' copyright = u'2013, Alex Gaynor and others.' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '0.11.0' # The full version, including alpha/beta/rc tags. release = '0.11.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". #html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'django-filterdoc' # -- Options for LaTeX output -------------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, author, documentclass [howto/manual]). latex_documents = [ ('asd', 'django-filter.tex', u'django-filter Documentation', u'Alex Gaynor and others.', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output -------------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('asd', 'django-filter', u'django-filter Documentation', [u'Alex Gaynor and others.'], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------------ # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('asd', 'django-filter', u'django-filter Documentation', u'Alex Gaynor and others.', 'django-filter', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' django-filter-0.11.0/docs/index.txt0000644000076500000240000000062312563340337017712 0ustar carltonstaff00000000000000============= django-filter ============= Django-filter is a generic, reusable application to alleviate writing some of the more mundane bits of view code. Specifically, it allows users to filter down a queryset based on a model's fields, displaying the form to let them do this. Contents: .. toctree:: :maxdepth: 1 install usage ref/filters ref/fields ref/widgets tests django-filter-0.11.0/docs/install.txt0000644000076500000240000000031512410601557020242 0ustar carltonstaff00000000000000Installing django-filter ------------------------ To install, simply place the ``django_filters`` directory somewhere on your ``PYTHONPATH``, and then add ``'django_filters'`` to your ``INSTALLED_APPS``. django-filter-0.11.0/docs/make.bat0000644000076500000240000001176612410601557017454 0ustar carltonstaff00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\django-filter.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\django-filter.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) :end django-filter-0.11.0/docs/Makefile0000644000076500000240000001303612563340337017504 0ustar carltonstaff00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-filter.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-filter.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/django-filter" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-filter" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." livehtml: sphinx-autobuild -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html django-filter-0.11.0/docs/ref/0000755000076500000240000000000012563340512016610 5ustar carltonstaff00000000000000django-filter-0.11.0/docs/ref/fields.txt0000644000076500000240000000145312563340337020627 0ustar carltonstaff00000000000000Fields Reference ================ ``IsoDateTimeField`` ~~~~~~~~~~~~~~~~~~~~ Extends ``django.forms.DateTimeField`` to allow parsing ISO 8601 formated dates, in addition to existing formats Defines a class level attribute ``ISO_8601`` as constant for the format. Sets ``input_formats = [ISO_8601]`` — this means that by default ``IsoDateTimeField`` will **only** parse ISO 8601 formated dates. You may set ``input_formats`` to your list of required formats as per the `DateTimeField Docs`_, using the ``ISO_8601`` class level attribute to specify the ISO 8601 format. :: f = IsoDateTimeField() f.input_formats = [IsoDateTimeField.ISO_8601] + DateTimeField.input_formats .. _`DateTimeField Docs`:https://docs.djangoproject.com/en/1.8/ref/forms/fields/#django.forms.DateTimeField.input_formats django-filter-0.11.0/docs/ref/filters.txt0000644000076500000240000002177412563340337021041 0ustar carltonstaff00000000000000Filter Reference ================ This is a reference document with a list of the filters and their arguments. Filters ------- ``CharFilter`` ~~~~~~~~~~~~~~ This filter does simple character matches, used with ``CharField`` and ``TextField`` by default. ``BooleanFilter`` ~~~~~~~~~~~~~~~~~ This filter matches a boolean, either ``True`` or ``False``, used with ``BooleanField`` and ``NullBooleanField`` by default. ``ChoiceFilter`` ~~~~~~~~~~~~~~~~ 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`` ~~~~~~~~~~~~~~~~~~~~~ The same as ``ChoiceFilter`` with the added possibility to convert value to match against. This could be done by using `coerce` parameter. An example use-case is limiting boolean choices to match against so only some predefined strings could be used as input of a boolean filter:: import django_filters from distutils.util import strtobool BOOLEAN_CHOICES = (('false', 'False'), ('true', 'True'),) class YourFilterSet(django_filters.FilterSet): ... flag = django_filters.TypedChoiceFilter(choices=BOOLEAN_CHOICES, coerce=strtobool) ``MultipleChoiceFilter`` ~~~~~~~~~~~~~~~~~~~~~~~~ The same as ``ChoiceFilter`` except the user can select multiple choices and the filter will form the OR of these choices by default to match items. The filter will form the AND of the selected choices when the ``conjoined=True`` argument is passed to this class. Multiple choices are represented in the query string by reusing the same key with different values (e.g. ''?status=Regular&status=Admin''). Advanced Use: Depending on your application logic, when all or no choices are selected, filtering may be a noop. In this case you may wish to avoid the filtering overhead, particularly of the `distinct` call. Set `always_filter` to False after instantiation to enable the default `is_noop` test. Override `is_noop` if you require a different test for your application. ``DateFilter`` ~~~~~~~~~~~~~~ Matches on a date. Used with ``DateField`` by default. ``TimeFilter`` ~~~~~~~~~~~~~~ Matches on a time. Used with ``TimeField`` by default. ``DateTimeFilter`` ~~~~~~~~~~~~~~~~~~ Matches on a date and time. Used with ``DateTimeField`` by default. ``IsoDateTimeFilter`` ~~~~~~~~~~~~~~~~~~~~~ Uses ``IsoDateTimeField`` to support filtering on ISO 8601 formatted dates, as are often used in APIs, and are employed by default by Django REST Framework. Example. :: class F(FilterSet): """Filter for Books by date published, using ISO 8601 formatted dates""" published = IsoDateTimeFilter() class Meta: model = Book fields = ['published'] ``ModelChoiceFilter`` ~~~~~~~~~~~~~~~~~~~~~ Similar to a ``ChoiceFilter`` except it works with related models, used for ``ForeignKey`` by default. If automatically instantiated ``ModelChoiceFilter`` will use the default ``QuerySet`` for the related field. If manually instantiated you **must** provide the ``queryset`` kwarg. ``ModelMultipleChoiceFilter`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Similar to a ``MultipleChoiceFilter`` except it works with related models, used for ``ManyToManyField`` by default. As with ``ModelChoiceFilter``, if automatically instantiated ``ModelMultipleChoiceFilter`` will use the default ``QuerySet`` for the related field. If manually instantiated you **must** provide the ``queryset`` kwarg. ``NumberFilter`` ~~~~~~~~~~~~~~~~ Filters based on a numerical value, used with ``IntegerField``, ``FloatField``, and ``DecimalField`` by default. ``NumericRangeFilter`` ~~~~~~~~~~~~~~~~~~~~~~ Filters where a value is between two numerical values, or greater than a minimum or less than a maximum where only one limit value is provided. This filter is designed to work with the Postgres Numerical Range Fields, including `IntegerRangeField`, `BigIntegerRangeField` and `FloatRangeField`, available since Django 1.8. The default widget used is the `RangeField`. RangeField lookup_types can be used, including `overlap`, `contains`, and `contained_by`. More lookups can be found in the Django docs ([https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/#querying-range-fields](https://docs.djangoproject.com/en/1.8/ref/contrib/postgres/fields/#querying-range-fields)). If the lower limit value is provided, the filter automatically defaults to `__startswith` as the lookup type and if only the upper limit value is provided, the filter uses `__endswith`. ``RangeFilter`` ~~~~~~~~~~~~~~~ Filters where a value is between two numerical values, or greater than a minimum or less than a maximum where only one limit value is provided. :: class F(FilterSet): """Filter for Books by Price""" price = RangeFilter() class Meta: model = Book fields = ['price'] qs = Book.objects.all().order_by('title') # Range: Books between 5€ and 15€ f = F({'price_0': '5', 'price_1': '15'}, queryset=qs) # Min-Only: Books costing more the 11€ f = F({'price_0': '11'}, queryset=qs) # Max-Only: Books costing less than 19€ f = F({'price_1': '19'}, queryset=qs) ``DateRangeFilter`` ~~~~~~~~~~~~~~~~~~~ Filter similar to the admin changelist date one, it has a number of common selections for working with date fields. ``DateFromToRangeFilter`` ~~~~~~~~~~~~~~~~~~~~~~~~~ Similar to a ``RangeFilter`` except it uses dates instead of numerical values. It can be used with ``DateField`` and ``DateTimeField``. ``TimeRangeFilter`` ~~~~~~~~~~~~~~~~~~~ Similar to a ``RangeFilter`` except it uses time format values instead of numerical values. It can be used with ``TimeField``. ``AllValuesFilter`` ~~~~~~~~~~~~~~~~~~~ This is a ``ChoiceFilter`` whose choices are the current values in the database. So if in the DB for the given field you have values of 5, 7, and 9 each of those is present as an option. This is similar to the default behavior of the admin. ``MethodFilter`` ~~~~~~~~~~~~~~~~~~~ This is a ``Filter`` that will allow you to run a method that exists on the filter set that this filter is a property of. Set the `action` to a string that will map to a method on the filter set class. Core Arguments -------------- ``name`` ~~~~~~~~ The name of the field this filter is supposed to filter on, if this is not provided it automatically becomes the filter's name on the ``FilterSet``. ``label`` ~~~~~~~~~ The label as it will apear in the HTML, analogous to a form field's label argument. ``widget`` ~~~~~~~~~~ The django.form Widget class which will represent the ``Filter``. In addition to the widgets that are included with Django that you can use there are additional ones that django-filter provides which may be useful: * ``django_filters.widgets.LinkWidget`` -- this displays the options in a mannner similar to the way the Django Admin does, as a series of links. The link for the selected option will have ``class="selected"``. ``action`` ~~~~~~~~~~ An optional callable that tells the filter how to handle the queryset. It recieves a ``QuerySet`` and the value to filter on and should return a ``Queryset`` that is filtered appropriately. ``lookup_type`` ~~~~~~~~~~~~~~~ The type of lookup that should be performed using the [Django ORM](https://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookups "Django's ORM Lookups"). All the normal options are allowed, and should be provided as a string. You can also provide either ``None`` or a ``list`` or a ``tuple``. If ``None`` is provided, then the user can select the lookup type from all the ones available in the Django ORM. If a ``list`` or ``tuple`` is provided, then the user can select from those options. ``distinct`` ~~~~~~~~~~~~ A boolean value that specifies whether the Filter will use distinct on the queryset. This option can be used to eliminate duplicate results when using filters that span related models. Defaults to ``False``. ``exclude`` ~~~~~~~~~~~ A boolean value that specifies whether the Filter should use ``filter`` or ``exclude`` on the queryset. Defaults to ``False``. ModelChoiceFilter and ModelMultipleChoiceFilter -------------- ``queryset`` ~~~~~~~~~~~ ``ModelChoiceFilter`` and ``ModelMultipleChoiceFilter`` require a queryset to operate on which must be passed as a kwarg. ``**kwargs`` ~~~~~~~~~~~~ Any extra keyword arguments will be provided to the accompanying form Field. This can be used to provide arguments like ``choices``. django-filter-0.11.0/docs/ref/widgets.txt0000644000076500000240000000121212411012542021002 0ustar carltonstaff00000000000000Widget Reference ================ This is a reference document with a list of the provided widgets and their arguments. ``LinkWidget`` ~~~~~~~~~~~~~~ This widget renders each option as a link, instead of an actual . It has one method that you can overide for additional customizability. ``option_string()`` should return a string with 3 Python keyword argument placeholders:: 1. ``attrs``: This is a string with all the attributes that will be on the final ```` tag. 2. ``query_string``: This is the query string for use in the ``href`` option on the ```` elemeent. 3. ``label``: This is the text to be displayed to the user. django-filter-0.11.0/docs/tests.txt0000644000076500000240000000262312552530365017747 0ustar carltonstaff00000000000000Running the django-filter tests =============================== The easiest way to run the django-filter tests is to check out the source code into a virtualenv, where you can install the test dependencies. django-filter uses a custom test runner to locate all of the tests, so a wrapper script is available to set up and run the test suite. .. note:: The following assumes you have `virtualenv`__ and `git`__ installed. __ http://www.virtualenv.org __ http://git-scm.com Set up a virtualenv for the test suite -------------------------------------- Run the following to create a new virtualenv to run the test suite in:: virtualenv django-filter-tests cd django-filter-tests . bin/activate Get a copy of django-filter --------------------------- Get the django-filter source code using the following command:: git clone https://github.com/alex/django-filter.git Switch to the django-filter directory:: cd django-filter Install the test dependencies ----------------------------- Run the following to install the test dependencies within the virutalenv:: pip install -r requirements/test.txt Run the django-filter tests:: python runtests.py Testing all supported versions ------------------------------ You can also use the excellent tox testing tool to run the tests against all supported versions of Python and Django. Install tox globally, and then simply run:: tox django-filter-0.11.0/docs/usage.txt0000644000076500000240000003017612563340337017715 0ustar carltonstaff00000000000000Using django-filter =================== Django-filter provides a simple way to filter down a queryset based on parameters a user provides. Say we have a ``Product`` model and we want to let our users filter which products they see on a list page. The model --------- Let's start with our model:: from django.db import models class Product(models.Model): name = models.CharField(max_length=255) price = models.DecimalField() description = models.TextField() release_date = models.DateField() manufacturer = models.ForeignKey(Manufacturer) The filter ---------- We have a number of fields and we want to let our users filter based on the price or the release_date. We create a ``FilterSet`` for this:: import django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['price', 'release_date'] As you can see this uses a very similar API to Django's ``ModelForm``. Just like with a ``ModelForm`` we can also override filters, or add new ones using a declarative syntax:: import django_filters class ProductFilter(django_filters.FilterSet): price = django_filters.NumberFilter(lookup_type='lt') class Meta: model = Product fields = ['price', 'release_date'] Filters take a ``lookup_type`` argument which specifies what lookup type to use with `Django's ORM`_. So here when a user entered a price it would show all Products with a price less than that. .. _`Django's ORM`: https://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookups **It's quite common to forget to set lookup type for `CharField`s/`TextField`s and wonder why search for "foo" doesn't return result for "foobar". It's because default lookup type is exact text, but you probably want `icontains` lookup field.** The FilterSet Meta class fields can additionally be set using a Dictionary to specify multiple ``lookup_type`` filters without significant code duplication:: import django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = {'price': ['lt', 'gt'], 'release_date': ['exact'], } The above would generate 'price__lt', 'price__gt' and 'release_date' filters. The filter lookup type keyword 'exact' is the default and therefore never added to a filter name. Items in the ``fields`` sequence in the ``Meta`` class may include "relationship paths" using Django's ``__`` syntax to filter on fields on a related model:: class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['manufacturer__country'] Filters also take any arbitrary keyword arguments which get passed onto the ``django.forms.Field`` initializer. These extra keyword arguments get stored in ``Filter.extra``, so it's possible to override the initializer of a ``FilterSet`` to add extra ones:: class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['manufacturer'] def __init__(self, *args, **kwargs): super(ProductFilter, self).__init__(*args, **kwargs) self.filters['manufacturer'].extra.update( {'empty_label': 'All Manufacturers'}) Like ``django.contrib.admin.ModelAdmin``, it is possible to override default filters for all the models fields of the same kind using ``filter_overrides``:: class ProductFilter(django_filters.FilterSet): filter_overrides = { models.CharField: { 'filter_class': django_filters.CharFilter, 'extra': lambda f: { 'lookup_type': 'icontains', } } } class Meta: model = Product fields = ['name'] MethodFilter ~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you want fine control over each individual filter attribute, you can use the ``MethodFilter`` filter. By passing in the name of a custom defined filter function as an ``action``, the filter attribute gets linked to the custom filter function. Here is an example of overriding the filter function of the filter attribute ``username`` :: class F(django_filters.FilterSet): username = MethodFilter(action='my_custom_filter') class Meta: model = User fields = ['username'] def my_custom_filter(self, queryset, value): return queryset.filter( username=value ) The filter function can also be defined outside of the filter class scope. Though you would need to pass in the actual function value, not it's name. :: def my_custom_filter(queryset, value): return queryset.filter( username=value ) class F(django_filters.FilterSet): # Notice: In this case, action accepts a func, not a string username = MethodFilter(action=filter_username) class Meta: model = User fields = ['username'] Lastly, when using a ``MethodFilter``, there is no need to define an action. You may simply do the following and ``filter_username`` will be auto-detected and used. :: class F(FilterSet): username = MethodFilter() class Meta: model = User fields = ['username'] def filter_username(self, queryset, value): return queryset.filter( username__contains='ke' ) Under the hood, if ``action`` not is defined, ``django_filter`` searches for a class method with a name that follows the pattern ``filter_{{ATTRIBUTE_NAME}}``. For example, if the attribute name is ``email``, then the filter class will be scanned for the filter function ``filter_email``. If no action is provided, and no filter class function is found, then the filter attribute will be left unfiltered. The view -------- Now we need to write a view:: def product_list(request): f = ProductFilter(request.GET, queryset=Product.objects.all()) return render_to_response('my_app/template.html', {'filter': f}) If a queryset argument isn't provided then all the items in the default manager of the model will be used. If you want to access the filtered objects in your views, for example if you want to paginate them, you can do that. They are in f.qs The URL conf ------------ We need a URL pattern to call the view:: url(r'^list$', views.product_list) The template ------------ And lastly we need a template:: {% extends "base.html" %} {% block content %}
        {{ filter.form.as_p }} {% for obj in filter %} {{ obj.name }} - ${{ obj.price }}
        {% endfor %} {% endblock %} And that's all there is to it! The ``form`` attribute contains a normal Django form, and when we iterate over the ``FilterSet`` we get the objects in the resulting queryset. Other Meta options ------------------ Ordering using ``order_by`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can allow the user to control ordering by providing the ``order_by`` argument in the Filter's Meta class. ``order_by`` can be either a ``list`` or ``tuple`` of field names, in which case those are the options, or it can be a ``bool`` which, if True, indicates that all fields that the user can filter on can also be sorted on. An example or ordering using a list:: import django_filters class ProductFilter(django_filters.FilterSet): price = django_filters.NumberFilter(lookup_type='lt') class Meta: model = Product fields = ['price', 'release_date'] order_by = ['price'] If you want to control the display of items in ``order_by``, you can set it to a list or tuple of 2-tuples in the format ``(field_name, display_name)``. This lets you override the displayed names for your ordering fields:: order_by = ( ('name', 'Company Name'), ('average_rating', 'Stars'), ) Note that the default query parameter name used for ordering is ``o``. You can override this by setting an ``order_by_field`` attribute on the ``FilterSet`` class to the string value you would like to use. Custom Forms using ``form`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~ The inner ``Meta`` class also takes an optional ``form`` argument. This is a form class from which ``FilterSet.form`` will subclass. This works similar to the ``form`` option on a ``ModelAdmin.`` Group fields with ``together`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The inner ``Meta`` class also takes an optional ``together`` argument. This is a list of lists, each containing field names. For convenience can be a single list/tuple when dealing with a single set of fields. Fields within a field set must either be all or none present in the request for ``FilterSet.form`` to be valid:: import django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['price', 'release_date', 'rating'] together = ['rating', 'price'] Non-Meta options ---------------- Note that these options do not go in the Meta class, they are specified directly in your FilterSet class. ``strict`` ~~~~~~~~~~ The ``strict`` option controls whether results are returned when an invalid value is specified by the user for any filter field. By default, ``strict`` is set to ``STRICTNESS.RETURN_NO_RESULTS`` meaning that an empty queryset is returned if any field contains an invalid value. You can loosen this behavior by setting ``strict`` to ``STRICTNESS.IGNORE`` which will effectively ignore a filter field if its value is invalid. A third option of ``STRICTNESS.RAISE_VALIDATION_ERROR`` will cause a ``ValidationError` to be raised if any field contains an invalid value. Overriding ``FilterSet`` methods -------------------------------- ``get_ordering_field()`` ~~~~~~~~~~~~~~~~~~~~~~~~ If you want to use a custom widget, or in any other way override the ordering field you can override the ``get_ordering_field()`` method on a ``FilterSet``. This method just needs to return a Form Field. Ordering on multiple fields, or other complex orderings can be achieved by overriding the ``FilterSet.get_order_by()`` method. This is passed the selected ``order_by`` value, and is expected to return an iterable of values to pass to ``QuerySet.order_by``. For example, to sort a ``User`` table by last name, then first name:: class UserFilter(django_filters.FilterSet): class Meta: order_by = ( ('username', 'Username'), ('last_name', 'Last Name') ) def get_order_by(self, order_value): if order_value == 'last_name': return ['last_name', 'first_name'] return super(UserFilter, self).get_order_by(order_value) Generic View ------------ In addition to the above usage there is also a class-based generic view included in django-filter, which lives at ``django_filters.views.FilterView``. You must provide either a ``model`` or ``filterset_class`` argument, similar to ``ListView`` in Django itself:: # urls.py from django.conf.urls import patterns, url from django_filters.views import FilterView from myapp.models import Product urlpatterns = patterns('', (r'^list/$', FilterView.as_view(model=Product)), ) You must provide a template at ``/_filter.html`` which gets the context parameter ``filter``. Additionally, the context will contain ``object_list`` which holds the filtered queryset. A legacy functional generic view is still included in django-filter, although its use is deprecated. It can be found at ``django_filters.views.object_filter``. You must provide the same arguments to it as the class based view:: # urls.py from django.conf.urls import patterns, url from myapp.models import Product urlpatterns = patterns('', (r'^list/$', 'django_filters.views.object_filter', {'model': Product}), ) The needed template and its context variables will also be the same as the class-based view above. django-filter-0.11.0/LICENSE0000644000076500000240000000271712410601557016120 0ustar carltonstaff00000000000000Copyright (c) Alex Gaynor and individual contributors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The names of its contributors may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. django-filter-0.11.0/MANIFEST.in0000644000076500000240000000035512410601557016645 0ustar carltonstaff00000000000000include AUTHORS include CHANGES.rst include LICENSE include README.rst include runshell.py include runtests.py recursive-include docs * recursive-include requirements * recursive-include tests * recursive-include django_filters/locale * django-filter-0.11.0/PKG-INFO0000644000076500000240000000663412563340512016212 0ustar carltonstaff00000000000000Metadata-Version: 1.1 Name: django-filter Version: 0.11.0 Summary: Django-filter is a reusable Django application for allowing users to filter querysets dynamically. Home-page: http://github.com/alex/django-filter/tree/master Author: Alex Gaynor Author-email: alex.gaynor@gmail.com License: BSD Description: Django Filter ============= Django-filter is a reusable Django application for allowing users to filter querysets dynamically. Full documentation on `read the docs`_. .. image:: https://secure.travis-ci.org/alex/django-filter.png?branch=master :target: http://travis-ci.org/alex/django-filter Requirements ------------ * Python 2.6+ * Django 1.4.5+ Installation ------------ Install using pip:: pip install django-filter Or clone the repo and add to your PYTHONPATH:: git clone git@github.com:alex/django-filter.git Usage ----- Django-filter can be used for generating interfaces similar to the Django admin's ``list_filter`` interface. It has an API very similar to Django's ``ModelForms``. For example, if you had a Product model you could have a filterset for it with the code:: import django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['name', 'price', 'manufacturer'] And then in your view you could do:: def product_list(request): filter = ProductFilter(request.GET, queryset=Product.objects.all()) return render_to_response('my_app/template.html', {'filter': filter}) Django-filters additionally supports specifying FilterSet fields using a dictionary to specify filters with lookup types:: import django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = {'name': ['exact', 'icontains'], 'price': ['exact', 'gte', 'lte'], } The filters will be available as 'name', 'name__icontains', 'price', 'price__gte', and 'price__lte' in the above example. Support ------- If you have questions about usage or development you can join the `mailing list`_. .. _`read the docs`: https://django-filter.readthedocs.org/en/latest/ .. _`mailing list`: http://groups.google.com/group/django-filter Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Framework :: Django django-filter-0.11.0/README.rst0000644000076500000240000000364712411012542016574 0ustar carltonstaff00000000000000Django Filter ============= Django-filter is a reusable Django application for allowing users to filter querysets dynamically. Full documentation on `read the docs`_. .. image:: https://secure.travis-ci.org/alex/django-filter.png?branch=master :target: http://travis-ci.org/alex/django-filter Requirements ------------ * Python 2.6+ * Django 1.4.5+ Installation ------------ Install using pip:: pip install django-filter Or clone the repo and add to your PYTHONPATH:: git clone git@github.com:alex/django-filter.git Usage ----- Django-filter can be used for generating interfaces similar to the Django admin's ``list_filter`` interface. It has an API very similar to Django's ``ModelForms``. For example, if you had a Product model you could have a filterset for it with the code:: import django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = ['name', 'price', 'manufacturer'] And then in your view you could do:: def product_list(request): filter = ProductFilter(request.GET, queryset=Product.objects.all()) return render_to_response('my_app/template.html', {'filter': filter}) Django-filters additionally supports specifying FilterSet fields using a dictionary to specify filters with lookup types:: import django_filters class ProductFilter(django_filters.FilterSet): class Meta: model = Product fields = {'name': ['exact', 'icontains'], 'price': ['exact', 'gte', 'lte'], } The filters will be available as 'name', 'name__icontains', 'price', 'price__gte', and 'price__lte' in the above example. Support ------- If you have questions about usage or development you can join the `mailing list`_. .. _`read the docs`: https://django-filter.readthedocs.org/en/latest/ .. _`mailing list`: http://groups.google.com/group/django-filter django-filter-0.11.0/requirements/0000755000076500000240000000000012563340512017627 5ustar carltonstaff00000000000000django-filter-0.11.0/requirements/docs.txt0000644000076500000240000000000712410601557021315 0ustar carltonstaff00000000000000Sphinx django-filter-0.11.0/requirements/maintainer.txt0000644000076500000240000000001412436107373022517 0ustar carltonstaff00000000000000bumpversion django-filter-0.11.0/requirements/test.txt0000644000076500000240000000006612563340337021356 0ustar carltonstaff00000000000000django-discover-runner mock coverage sphinx-autobuild django-filter-0.11.0/requirements/travis-ci.txt0000644000076500000240000000004512410601557022270 0ustar carltonstaff00000000000000django-discover-runner mock coverage django-filter-0.11.0/runshell.py0000755000076500000240000000136212410601557017317 0ustar carltonstaff00000000000000#!/usr/bin/env python import sys from django.conf import settings from django.core.management import call_command from django.core.management import execute_from_command_line if not settings.configured: settings.configure( DATABASES={ 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:', }, }, INSTALLED_APPS=( 'django_filters', 'tests', ), ROOT_URLCONF=None, USE_TZ=True, SECRET_KEY='foobar' ) def runshell(): call_command('syncdb', interactive=False) argv = sys.argv[:1] + ['shell'] + sys.argv[1:] execute_from_command_line(argv) if __name__ == '__main__': runshell() django-filter-0.11.0/runtests.py0000755000076500000240000000174012411012542017341 0ustar carltonstaff00000000000000#!/usr/bin/env python import sys from django import VERSION from django.conf import settings from django.core.management import execute_from_command_line if not settings.configured: test_runners_args = {} if VERSION < (1, 6): test_runners_args = { 'TEST_RUNNER': 'discover_runner.DiscoverRunner', } settings.configure( DATABASES={ 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': ':memory:', }, }, INSTALLED_APPS=( 'django.contrib.contenttypes', 'django.contrib.auth', 'django_filters', 'tests', ), ROOT_URLCONF=None, USE_TZ=True, SECRET_KEY='foobar', SILENCED_SYSTEM_CHECKS=['1_7.W001'], **test_runners_args ) def runtests(): argv = sys.argv[:1] + ['test'] + sys.argv[1:] execute_from_command_line(argv) if __name__ == '__main__': runtests() django-filter-0.11.0/setup.cfg0000644000076500000240000000016512563340512016727 0ustar carltonstaff00000000000000[metadata] license-file = LICENSE [wheel] universal = 1 [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 django-filter-0.11.0/setup.py0000644000076500000240000000315012563340337016622 0ustar carltonstaff00000000000000import os import sys from setuptools import setup, find_packages f = open('README.rst') readme = f.read() f.close() version = '0.11.0' if sys.argv[-1] == 'publish': os.system("python setup.py sdist upload") os.system("python setup.py bdist_wheel upload") print("You probably want to also tag the version now:") print(" git tag -a %s -m 'version %s'" % (version, version)) print(" git push --tags") sys.exit() setup( name='django-filter', version=version, description=('Django-filter is a reusable Django application for allowing' ' users to filter querysets dynamically.'), long_description=readme, author='Alex Gaynor', author_email='alex.gaynor@gmail.com', url='http://github.com/alex/django-filter/tree/master', packages=find_packages(exclude=['tests']), package_data = { 'django_filters': [ 'locale/*/LC_MESSAGES/*', ], }, license='BSD', classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Web Environment', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.2', 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Framework :: Django', ], include_package_data=True, zip_safe=False, ) django-filter-0.11.0/tests/0000755000076500000240000000000012563340512016246 5ustar carltonstaff00000000000000django-filter-0.11.0/tests/__init__.py0000644000076500000240000000000012410601557020345 0ustar carltonstaff00000000000000django-filter-0.11.0/tests/__init__.pyc0000644000076500000240000000023412410601743020516 0ustar carltonstaff00000000000000ó o#Tc@sdS(N((((sE/Users/carlton/Documents/Django-Stack/django-filter/tests/__init__.pytsdjango-filter-0.11.0/tests/models.py0000644000076500000240000001072312436107373020113 0ustar carltonstaff00000000000000from __future__ import absolute_import from __future__ import unicode_literals from django import forms from django.db import models from django.utils.encoding import python_2_unicode_compatible STATUS_CHOICES = ( (0, 'Regular'), (1, 'Manager'), (2, 'Admin'), ) # classes for testing filters with inherited fields class SubCharField(models.CharField): pass class SubSubCharField(SubCharField): pass class SubnetMaskField(models.Field): empty_strings_allowed = False description = "Subnet Mask" def __init__(self, *args, **kwargs): kwargs['max_length'] = 15 models.Field.__init__(self, *args, **kwargs) def get_internal_type(self): return "IPAddressField" def formfield(self, **kwargs): defaults = {'form_class': forms.IPAddressField} defaults.update(kwargs) return super(SubnetMaskField, self).formfield(**defaults) @python_2_unicode_compatible 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) is_active = models.BooleanField(default=False) favorite_books = models.ManyToManyField('Book', related_name='lovers') def __str__(self): return self.username @python_2_unicode_compatible class AdminUser(User): class Meta: proxy = True def __str__(self): return "%s (ADMIN)" % self.username @python_2_unicode_compatible class Comment(models.Model): text = models.TextField() author = models.ForeignKey(User, related_name='comments') date = models.DateField() time = models.TimeField() def __str__(self): return "%s said %s" % (self.author, self.text[:25]) class Article(models.Model): published = models.DateTimeField() author = models.ForeignKey(User, null=True) def __str__(self): if self.author_id: return "%s on %s" % (self.author, self.published) return "Anonymous on %s" % self.published @python_2_unicode_compatible class Book(models.Model): title = models.CharField(max_length=100) price = models.DecimalField(max_digits=6, decimal_places=2) average_rating = models.FloatField() def __str__(self): return self.title class Place(models.Model): name = models.CharField(max_length=100) class Meta: abstract = True class Restaurant(Place): serves_pizza = models.BooleanField(default=False) class NetworkSetting(models.Model): ip = models.IPAddressField() mask = SubnetMaskField() @python_2_unicode_compatible class Company(models.Model): name = models.CharField(max_length=100) def __str__(self): return self.name class Meta: ordering = ['name'] @python_2_unicode_compatible class Location(models.Model): company = models.ForeignKey(Company, related_name='locations') name = models.CharField(max_length=100) zip_code = models.CharField(max_length=10) open_days = models.CharField(max_length=7) def __str__(self): return '%s: %s' % (self.company.name, self.name) class Account(models.Model): name = models.CharField(max_length=100) in_good_standing = models.BooleanField(default=False) friendly = models.BooleanField(default=False) class Profile(models.Model): account = models.OneToOneField(Account, related_name='profile') likes_coffee = models.BooleanField(default=False) likes_tea = models.BooleanField(default=False) class BankAccount(Account): amount_saved = models.IntegerField(default=0) class Node(models.Model): name = models.CharField(max_length=20) adjacents = models.ManyToManyField('self') class DirectedNode(models.Model): name = models.CharField(max_length=20) outbound_nodes = models.ManyToManyField('self', symmetrical=False, related_name='inbound_nodes') class Worker(models.Model): name = models.CharField(max_length=100) class HiredWorker(models.Model): salary = models.IntegerField() hired_on = models.DateField() worker = models.ForeignKey(Worker) business = models.ForeignKey('Business') class Business(models.Model): name = models.CharField(max_length=100) employees = models.ManyToManyField(Worker, through=HiredWorker, related_name='employers') django-filter-0.11.0/tests/models.pyc0000644000076500000240000002325312445035263020256 0ustar carltonstaff00000000000000ó ûŽxTc@@sˆddlmZddlmZddlmZddlmZddlmZd6d7d8fZ d ej fd „ƒYZ d e fd„ƒYZ dej fd„ƒYZedejfd„ƒYƒZedefd„ƒYƒZedejfd„ƒYƒZdejfd„ƒYZedejfd„ƒYƒZdejfd„ƒYZdefd„ƒYZdejfd „ƒYZed!ejfd"„ƒYƒZed#ejfd$„ƒYƒZd%ejfd&„ƒYZd'ejfd(„ƒYZd)efd*„ƒYZd+ejfd,„ƒYZd-ejfd.„ƒYZd/ejfd0„ƒYZd1ejfd2„ƒYZ d3ejfd4„ƒYZ!d5S(9i(tabsolute_import(tunicode_literals(tforms(tmodels(tpython_2_unicode_compatibleuRegulariuManageriuAdmint SubCharFieldcB@seZRS((t__name__t __module__(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyRstSubSubCharFieldcB@seZRS((RR(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyRstSubnetMaskFieldcB@s/eZeZdZd„Zd„Zd„ZRS(u Subnet MaskcO@s$d|dt DecimalFieldtpricet FloatFieldtaverage_ratingR(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyR;Ys tPlacecB@s-eZejddƒZddd„ƒYZRS(RidR*cB@seZeZRS((RRR+tabstract(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyR*fs((RRRRtnameR*(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyRCcst RestaurantcB@seZejdeƒZRS(R(RRRR%Rt serves_pizza(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyRFjstNetworkSettingcB@seZejƒZeƒZRS((RRRRtipR tmask(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyRHns tCompanycB@s6eZejddƒZd„Zddd„ƒYZRS(RidcC@s|jS(N(RE(R ((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyRwsR*cB@seZdgZRS(uname(RRtordering(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyR*zs((RRRRRERR*(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyRKss tLocationcB@s\eZejeddƒZejddƒZejddƒZejddƒZ d„Z RS(Ru locationsRidi icC@sd|jj|jfS(Nu%s: %s(tcompanyRE(R ((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyR…s( RRRR1RKRNRREtzip_codet open_daysR(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyRM~s tAccountcB@s>eZejddƒZejdeƒZejdeƒZRS(RidR( RRRRRER%Rtin_good_standingtfriendly(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyRQ‰stProfilecB@sAeZejeddƒZejdeƒZejdeƒZ RS(RuprofileR( RRRt OneToOneFieldRQtaccountR%Rt likes_coffeet likes_tea(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyRTst BankAccountcB@seZejddƒZRS(Ri(RRRR"t amount_saved(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyRY•stNodecB@s)eZejddƒZejdƒZRS(Riuself(RRRRRER't adjacents(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyR[™st DirectedNodecB@s5eZejddƒZejddeddƒZRS(Riuselft symmetricalRu inbound_nodes(RRRRRER'Rtoutbound_nodes(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyR]žs tWorkercB@seZejddƒZRS(Rid(RRRRRE(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyR`¥st HiredWorkercB@s>eZejƒZejƒZejeƒZ ejdƒZ RS(uBusiness( RRRR"tsalaryR2thired_onR1R`tworkertbusiness(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyRa©s  tBusinesscB@s5eZejddƒZejededdƒZRS(RidtthroughRu employers( RRRRRER'R`Rat employees(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pyRf°s N(iuRegular(iuManager(iuAdmin("t __future__RRtdjangoRt django.dbRtdjango.utils.encodingRR#RRRR R tModelRR)R-R6R;RCRFRHRKRMRQRTRYR[R]R`RaRf(((sC/Users/carlton/Documents/Django-Stack/django-filter/tests/models.pytsD      django-filter-0.11.0/tests/templates/0000755000076500000240000000000012563340512020244 5ustar carltonstaff00000000000000django-filter-0.11.0/tests/templates/tests/0000755000076500000240000000000012563340512021406 5ustar carltonstaff00000000000000django-filter-0.11.0/tests/templates/tests/book_filter.html0000644000076500000240000000011112410601557024564 0ustar carltonstaff00000000000000{{ filter.form }} {% for obj in filter.qs %} {{ obj }} {% endfor %} django-filter-0.11.0/tests/test_fields.py0000644000076500000240000001023312563340337021131 0ustar carltonstaff00000000000000from __future__ import absolute_import from __future__ import unicode_literals from datetime import datetime, time import decimal import sys if sys.version_info >= (2, 7): import unittest else: # pragma: nocover from django.utils import unittest # noqa import django from django import forms from django.test import TestCase from django_filters.widgets import RangeWidget from django_filters.fields import ( RangeField, LookupTypeField, Lookup, DateRangeField, TimeRangeField, IsoDateTimeField) def to_d(float_value): return decimal.Decimal('%.2f' % float_value) class RangeFieldTests(TestCase): def test_field(self): f = RangeField() self.assertEqual(len(f.fields), 2) def test_clean(self): w = RangeWidget() f = RangeField(widget=w) self.assertEqual( f.clean(['12.34', '55']), slice(to_d(12.34), to_d(55))) class DateRangeFieldTests(TestCase): def test_field(self): f = DateRangeField() self.assertEqual(len(f.fields), 2) def test_clean(self): w = RangeWidget() f = DateRangeField(widget=w) self.assertEqual( f.clean(['2015-01-01', '2015-01-10']), slice(datetime(2015, 1, 1, 0, 0 , 0), datetime(2015, 1, 10, 23, 59, 59, 999999))) class TimeRangeFieldTests(TestCase): def test_field(self): f = DateRangeField() self.assertEqual(len(f.fields), 2) def test_clean(self): w = RangeWidget() f = TimeRangeField(widget=w) self.assertEqual( f.clean(['10:15', '12:30']), slice(time(10, 15, 0), time(12, 30, 0))) class LookupTypeFieldTests(TestCase): def test_field(self): inner = forms.DecimalField() f = LookupTypeField(inner, [('gt', 'gt'), ('lt', 'lt')]) self.assertEqual(len(f.fields), 2) def test_clean(self): inner = forms.DecimalField() f = LookupTypeField(inner, [('gt', 'gt'), ('lt', 'lt')]) self.assertEqual( f.clean(['12.34', 'lt']), Lookup(to_d(12.34), 'lt')) @unittest.skipIf(django.VERSION >= (1, 6), 'Django 1.6 uses html5 fields') def test_render(self): inner = forms.DecimalField() f = LookupTypeField(inner, [('gt', 'gt'), ('lt', 'lt')]) self.assertHTMLEqual(f.widget.render('price', ''), """ """) self.assertHTMLEqual(f.widget.render('price', ['abc', 'lt']), """ """) @unittest.skipUnless(django.VERSION >= (1, 6), 'Django 1.6 uses html5 fields') def test_render_used_html5(self): inner = forms.DecimalField() f = LookupTypeField(inner, [('gt', 'gt'), ('lt', 'lt')]) self.assertHTMLEqual(f.widget.render('price', ''), """ """) self.assertHTMLEqual(f.widget.render('price', ['abc', 'lt']), """ """) class IsoDateTimeFieldTests(TestCase): def test_datetime_string_is_parsed(self): f = IsoDateTimeField() d = f.strptime("2015-07-19T13:34:51.759", IsoDateTimeField.ISO_8601) self.assertTrue(isinstance(d, datetime)) def test_datetime_string_with_timezone_is_parsed(self): f = IsoDateTimeField() d = f.strptime("2015-07-19T13:34:51.759+01:00", IsoDateTimeField.ISO_8601) self.assertTrue(isinstance(d, datetime))django-filter-0.11.0/tests/test_fields.pyc0000644000076500000240000001631612562710160021276 0ustar carltonstaff00000000000000ó ËUc@@saddlmZddlmZddlmZmZddlZddlZejdkrlddlZnddl mZddl Z ddl m Z dd l m Z dd lmZdd lmZmZmZmZmZmZd „Zd e fd„ƒYZde fd„ƒYZde fd„ƒYZde fd„ƒYZde fd„ƒYZdS(i(tabsolute_import(tunicode_literals(tdatetimettimeNii(tunittest(tforms(tTestCase(t RangeWidget(t RangeFieldtLookupTypeFieldtLookuptDateRangeFieldtTimeRangeFieldtIsoDateTimeFieldcC@stjd|ƒS(Nu%.2f(tdecimaltDecimal(t float_value((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pytto_dstRangeFieldTestscB@seZd„Zd„ZRS(cC@s&tƒ}|jt|jƒdƒdS(Ni(Rt assertEqualtlentfields(tselftf((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyt test_fields cC@sPtƒ}td|ƒ}|j|jddgƒttdƒtdƒƒƒdS(Ntwidgetu12.34u55g®Gáz®(@i7(RRRtcleantsliceR(RtwR((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyt test_cleans  (t__name__t __module__RR(((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyRs tDateRangeFieldTestscB@seZd„Zd„ZRS(cC@s&tƒ}|jt|jƒdƒdS(Ni(R RRR(RR((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyR*s c C@sqtƒ}td|ƒ}|j|jddgƒttddddddƒtddddd d d ƒƒƒdS( NRu 2015-01-01u 2015-01-10ißiii ii;i?B(RR RRRR(RRR((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyR.s  (RRRR(((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyR (s tTimeRangeFieldTestscB@seZd„Zd„ZRS(cC@s&tƒ}|jt|jƒdƒdS(Ni(R RRR(RR((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyR:s cC@s\tƒ}td|ƒ}|j|jddgƒttdddƒtdddƒƒƒdS( NRu10:15u12:30i iii i(RR RRRR(RRR((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyR>s  (RRRR(((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyR!8s tLookupTypeFieldTestscB@sbeZd„Zd„Zejejdkdƒd„ƒZej ejdkdƒd„ƒZ RS( cC@s>tjƒ}t|ddgƒ}|jt|jƒdƒdS(Nugtulti(ugtugt(ultult(Rt DecimalFieldR RRR(RtinnerR((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyRIs cC@sStjƒ}t|ddgƒ}|j|jddgƒttdƒdƒƒdS(Nugtultu12.34g®Gáz®(@(ugtugt(ultult(RR#R RRR R(RR$R((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyRNs  iiuDjango 1.6 uses html5 fieldscC@sitjƒ}t|dd gƒ}|j|jjddƒdƒ|j|jjdddgƒdƒdS( NugtultupriceuuÉ uabcué (ugtugt(ultult(RR#R tassertHTMLEqualRtrender(RR$R((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyt test_renderUs  cC@sitjƒ}t|dd gƒ}|j|jjddƒdƒ|j|jjdddgƒdƒdS( NugtultupriceuuÖ uabcuö (ugtugt(ultult(RR#R R%RR&(RR$R((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyttest_render_used_html5gs  (ii(ii( RRRRRtskipIftdjangotVERSIONR't skipUnlessR((((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyR"Gs   tIsoDateTimeFieldTestscB@seZd„Zd„ZRS(cC@s8tƒ}|jdtjƒ}|jt|tƒƒdS(Nu2015-07-19T13:34:51.759(R tstrptimetISO_8601t assertTruet isinstanceR(RRtd((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyttest_datetime_string_is_parsed|s cC@s8tƒ}|jdtjƒ}|jt|tƒƒdS(Nu2015-07-19T13:34:51.759+01:00(R R.R/R0R1R(RRR2((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyt,test_datetime_string_with_timezone_is_parseds (RRR3R4(((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyR-zs (ii(t __future__RRRRRtsyst version_infoRt django.utilsR*Rt django.testRtdjango_filters.widgetsRtdjango_filters.fieldsRR R R R R RRR R!R"R-(((sH/Users/carlton/Documents/Django-Stack/django-filter/tests/test_fields.pyts$   . 3django-filter-0.11.0/tests/test_filtering.py0000644000076500000240000013323112563340337021652 0ustar carltonstaff00000000000000from __future__ import absolute_import from __future__ import unicode_literals import datetime import mock import sys if sys.version_info >= (2, 7): import unittest else: # pragma: nocover from django.utils import unittest # noqa 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 MethodFilter from django_filters.filters import MultipleChoiceFilter from django_filters.filters import ModelMultipleChoiceFilter 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 BankAccount from .models import Profile from .models import Node from .models import DirectedNode 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 IntegerFilterTest(TestCase): def test_filtering(self): default_values = { 'in_good_standing': True, 'friendly': False, } b1 = BankAccount.objects.create(amount_saved=0, **default_values) b2 = BankAccount.objects.create(amount_saved=3, **default_values) b3 = BankAccount.objects.create(amount_saved=10, **default_values) class F(FilterSet): class Meta: model = BankAccount fields = ['amount_saved'] qs = BankAccount.objects.all() f = F(queryset=qs) self.assertQuerysetEqual(f.qs, [b1.pk, b2.pk, b3.pk], lambda o: o.pk, ordered=False) f = F({'amount_saved': '10'}, queryset=qs) self.assertQuerysetEqual(f.qs, [b3.pk], lambda o: o.pk) f = F({'amount_saved': '0'}, queryset=qs) self.assertQuerysetEqual(f.qs, [b1.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) 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): 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, False) 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, False) 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, False) 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] self.alex = alex 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) def test_filtering_dictionary(self): class F(FilterSet): class Meta: model = User fields = {'favorite_books': ['exact']} 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_filtering_on_all_of_subset_of_choices(self): class F(FilterSet): class Meta: model = User fields = ['favorite_books'] def __init__(self, *args, **kwargs): super(F, self).__init__(*args, **kwargs) # This filter has a limited number of choices. self.filters['favorite_books'].extra.update({ 'queryset': Book.objects.filter(id__in=[1, 2]) }) self.filters['favorite_books'].required = True qs = User.objects.all().order_by('username') # Select all the given choices. f = F({'favorite_books': ['1', '2']}, queryset=qs) # The results should only include matching users - not Jacob. self.assertQuerysetEqual(f.qs, ['aaron', 'alex'], lambda o: o.username) def test_filtering_on_non_required_fields(self): # See issue #132 - filtering with all options on a non-required # field should exclude any results where the field is null. class F(FilterSet): author = ModelMultipleChoiceFilter(queryset=User.objects.all()) class Meta: model = Article fields = ['author'] published = now() Article.objects.create(published=published, author=self.alex) Article.objects.create(published=published, author=self.alex) Article.objects.create(published=published) qs = Article.objects.all() # Select all authors. authors = [ str(user.id) for user in User.objects.all() ] f = F({'author': authors}, queryset=qs) # The results should not include anonymous articles self.assertEqual( set(f.qs), set(Article.objects.exclude(author__isnull=True)), ) 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_single_lookup_type_dictionary(self): class F(FilterSet): class Meta: model = Book fields = {'price': ['lt']} f = F({'price__lt': 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) Book.objects.create(title="Refund", price='-10.0', average_rating=5.0) Book.objects.create(title="Free Book", price='0.0', average_rating=0.0) 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', 'Free Book', 'Rainbow Six', 'Refund', '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) f = F({'price_0': '11'}, queryset=qs) self.assertQuerysetEqual(f.qs, ['Rainbow Six', 'Snowcrash'], lambda o: o.title) f = F({'price_1': '19'}, queryset=qs) self.assertQuerysetEqual(f.qs, ['Ender\'s Game', 'Free Book', 'Rainbow Six', 'Refund'], lambda o: o.title) f = F({'price_0': '0', 'price_1': '12'}, queryset=qs) self.assertQuerysetEqual(f.qs, ['Ender\'s Game', 'Free Book'], lambda o: o.title) f = F({'price_0': '-11', 'price_1': '0'}, queryset=qs) self.assertQuerysetEqual(f.qs, ['Free Book', 'Refund'], lambda o: o.title) f = F({'price_0': '0', 'price_1': '0'}, queryset=qs) self.assertQuerysetEqual(f.qs, ['Free Book'], 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()) def test_filtering_without_strict(self): User.objects.create(username='alex') User.objects.create(username='jacob') User.objects.create(username='aaron') class F(FilterSet): username = AllValuesFilter() strict = False 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 MethodFilterTests(TestCase): def test_filtering(self): User.objects.create(username='alex') User.objects.create(username='jacob') User.objects.create(username='aaron') class F(FilterSet): username = MethodFilter(action='filter_username') class Meta: model = User fields = ['username'] def filter_username(self, queryset, value): return queryset.filter( username=value ) 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()) def test_filtering_external(self): User.objects.create(username='alex') User.objects.create(username='jacob') User.objects.create(username='aaron') def filter_username(queryset, value): return queryset.filter( username=value ) class F(FilterSet): username = MethodFilter(action=filter_username) 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()) def test_filtering_default_attribute_action(self): User.objects.create(username='mike') User.objects.create(username='jake') User.objects.create(username='aaron') class F(FilterSet): username = MethodFilter() class Meta: model = User fields = ['username'] def filter_username(self, queryset, value): return queryset.filter( username__contains='ke' ) self.assertEqual(list(F().qs), list(User.objects.all())) self.assertEqual(list(F({'username': 'mike'})), [User.objects.get(username='mike'), User.objects.get(username='jake')],) self.assertEqual(list(F({'username': 'jake'})), [User.objects.get(username='mike'), User.objects.get(username='jake')]) self.assertEqual(list(F({'username': 'aaron'})), [User.objects.get(username='mike'), User.objects.get(username='jake')]) def test_filtering_default(self): User.objects.create(username='mike') User.objects.create(username='jake') User.objects.create(username='aaron') class F(FilterSet): username = MethodFilter() email = MethodFilter() class Meta: model = User fields = ['username'] self.assertEqual(list(F().qs), list(User.objects.all())) self.assertEqual(list(F({'username': 'mike'})), list(User.objects.all())) self.assertEqual(list(F({'username': 'jake'})), list(User.objects.all())) self.assertEqual(list(F({'username': 'aaron'})), 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_o2o_relation_dictionary(self): class F(FilterSet): class Meta: model = Profile fields = {'account': ['exact'], } 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): class F(FilterSet): class Meta: model = Account fields = ('profile',) f = F() self.assertEqual(f.qs.count(), 4) f = F({'profile': 1}) self.assertEqual(f.qs.count(), 1) self.assertQuerysetEqual(f.qs, [1], lambda o: o.pk) 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, False) 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, False) 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, False) 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) class F(FilterSet): class Meta: model = User fields = ['comments'] qs = User.objects.all() f = F({'comments': [2]}, queryset=qs) self.assertQuerysetEqual(f.qs, ['alex'], lambda o: o.username) class F(FilterSet): comments = 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): class F(FilterSet): class Meta: model = Book fields = ['lovers'] qs = Book.objects.all().order_by('title') f = F({'lovers': [1]}, queryset=qs) self.assertQuerysetEqual( f.qs, ["Ender's Game", "Rainbow Six"], lambda o: o.title) 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 SymmetricalSelfReferentialRelationshipTests(TestCase): def setUp(self): n1 = Node.objects.create(name='one') n2 = Node.objects.create(name='two') n3 = Node.objects.create(name='three') n4 = Node.objects.create(name='four') n1.adjacents.add(n2) n2.adjacents.add(n3) n2.adjacents.add(n4) n4.adjacents.add(n1) def test_relation(self): class F(FilterSet): class Meta: model = Node fields = ['adjacents'] qs = Node.objects.all().order_by('pk') f = F({'adjacents': ['1']}, queryset=qs) self.assertQuerysetEqual(f.qs, [2, 4], lambda o: o.pk) class NonSymmetricalSelfReferentialRelationshipTests(TestCase): def setUp(self): n1 = DirectedNode.objects.create(name='one') n2 = DirectedNode.objects.create(name='two') n3 = DirectedNode.objects.create(name='three') n4 = DirectedNode.objects.create(name='four') n1.outbound_nodes.add(n2) n2.outbound_nodes.add(n3) n2.outbound_nodes.add(n4) n4.outbound_nodes.add(n1) def test_forward_relation(self): class F(FilterSet): class Meta: model = DirectedNode fields = ['outbound_nodes'] qs = DirectedNode.objects.all().order_by('pk') f = F({'outbound_nodes': ['1']}, queryset=qs) self.assertQuerysetEqual(f.qs, [4], lambda o: o.pk) def test_reverse_relation(self): class F(FilterSet): class Meta: model = DirectedNode fields = ['inbound_nodes'] qs = DirectedNode.objects.all().order_by('pk') f = F({'inbound_nodes': ['1']}, queryset=qs) self.assertQuerysetEqual(f.qs, [2], lambda o: o.pk) 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) django-filter-0.11.0/tests/test_filtering.pyc0000644000076500000240000024727412562714615022035 0ustar carltonstaff00000000000000ó „—ËUc@@sóddlmZddlmZddlZddlZddlZejdMkrbddlZnddlmZddl m Z ddlm Z dd l m Z dd lmZdd lmZdd lmZdd lmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlmZddlm Z ddlm!Z!ddlm"Z"ddlm#Z#ddlm$Z$ddlm%Z%dd lm&Z&dd!lm'Z'd"e fd#„ƒYZ(d$e fd%„ƒYZ)d&e fd'„ƒYZ*d(e fd)„ƒYZ+d*e fd+„ƒYZ,d,e fd-„ƒYZ-d.e fd/„ƒYZ.d0e fd1„ƒYZ/d2e fd3„ƒYZ0d4e fd5„ƒYZ1d6e fd7„ƒYZ2d8e fd9„ƒYZ3ej4d:ƒd;e fd<„ƒYƒZ5d=e fd>„ƒYZ6d?e fd@„ƒYZ7dAe fdB„ƒYZ8dCe fdD„ƒYZ9dEe fdF„ƒYZ:dGe fdH„ƒYZ;dIe fdJ„ƒYZ<dKe fdL„ƒYZ=dS(Ni(tabsolute_import(tunicode_literalsNii(tunittest(tTestCase(tsix(tnow(ttimezone(t FilterSet(tAllValuesFilter(t CharFilter(t ChoiceFilter(tDateRangeFilter(t MethodFilter(tMultipleChoiceFilter(tModelMultipleChoiceFilter(t NumberFilter(t RangeFilteri(tUser(tComment(tBook(tArticle(tCompany(tLocation(tAccount(t BankAccount(tProfile(tNode(t DirectedNode(tSTATUS_CHOICEStCharFilterTestscB@seZd„ZRS(cC@stjjddddddƒ}tjjddddddƒ}tjjddddddƒ}d tfd „ƒY}tjjƒ}|d |ƒ}|j|j|j|j|jgd „d tƒ|idd6d |ƒ}|j|j|jgd„ƒdS(Nttitleu Ender's Gametpriceu1.00taverage_ratingg@u Rainbow Sixu SnowcrashtFcB@seZddd„ƒYZRS(tMetacB@seZeZdgZRS(utitle(t__name__t __module__Rtmodeltfields(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR";s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!:stquerysetcS@s|jS(N(tpk(to((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pytBstorderedutitlecS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Ds( RtobjectstcreateRtalltassertQuerysetEqualtqsR(tFalse(tselftb1tb2tb3R!R0tf((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_filtering2s   !(R#R$R7(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR0stIntegerFilterTestcB@seZd„ZRS(cC@s5itd6td6}tjjdd|}tjjdd|}tjjdd|}dtfd„ƒY}tjjƒ}|d |ƒ}|j|j|j |j |j gd „d tƒ|id d 6d |ƒ}|j|j|j gd„ƒ|idd 6d |ƒ}|j|j|j gd„ƒdS(Nuin_good_standingufriendlyt amount_savediii R!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(u amount_saved(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Ss((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!RsR'cS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*ZsR+u10u amount_savedcS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*\su0cS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*^s( tTrueR1RR,R-RR.R/R0R((R2tdefault_valuesR3R4R5R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR7Is !(R#R$R7(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR8GstBooleanFilterTestscB@seZd„ZRS(cC@s%tjjdddtƒtjjdddtƒtjjdddtƒdtfd„ƒY}tjjƒ}|idd 6d |ƒ}|j|jdgd „tƒ|id d 6d |ƒ}|j|jddgd „tƒ|idd 6d |ƒ}|j|jdddgd„tƒdS(Ntusernameualext is_activeujacobuaaronR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(u is_active(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"is((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!hsu2u is_activeR'cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*qsu3cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*vsu1cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*{s( RR,R-R1R:RR.R/R0(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR7cs     (R#R$R7(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR<astChoiceFilterTestscB@seZd„Zd„ZRS(cC@sHtjjddddƒtjjddddƒtjjddddƒtjjdddd ƒd tfd „ƒY}|ƒ}|j|jddddgd „tƒ|id d6ƒ}|j|jdgd„tƒ|idd6ƒ}|j|jddgd„tƒ|idd6ƒ}|j|jdgd„tƒdS(NR=ualextstatusiujacobiuaaronucarliR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(ustatus(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"‡s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!†scS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Žsu1ustatuscS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*su2cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*”su0cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*—s(RR,R-RR/R0R1(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR7€s     cC@sHtjjddddƒtjjddddƒtjjddddƒtjjdddd ƒd tfd „ƒY}|ƒ}|j|jddddgd „tƒ|id d6ƒ}|j|jdgd„tƒ|idd6ƒ}|j|jddgd„tƒ|idd6ƒ}|j|jdgd„tƒdS(us Test for #30. If you explicitly declare ChoiceFilter fields you **MUST** pass `choices`. R=ualexR@iujacobiuaaronucarliR!cB@s*eZedeƒZddd„ƒYZRS(tchoicesR"cB@seZeZdgZRS(ustatus(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"§s((R#R$R RR@R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!¥scS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*®su1ustatuscS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*°su2cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*´su0cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*·sN(RR,R-RR/R0R1(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt*test_filtering_on_explicitly_defined_fieldšs     (R#R$R7RB(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR?~s tMultipleChoiceFilterTestscB@seZd„ZRS(cC@sŠtjjddddƒtjjddddƒtjjddddƒtjjdddd ƒd tfd „ƒY}tjjƒjd ƒ}|d |ƒ}|j|jddddgd„tƒ|idgd6d |ƒ}|j|jdgd„ƒ|iddgd6d |ƒ}|j|jddgd„ƒ|idddgd6d |ƒ}|j|jddddgd„ƒdS(NR=ualexR@iujacobiuaaronucarliR!cB@s*eZedeƒZddd„ƒYZRS(RAR"cB@seZeZdgZRS(ustatus(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Æs((R#R$R RR@R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!ÃsuusernameR'cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Îsu0ustatuscS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Òsu1cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Ösu2cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Ús( RR,R-RR.torder_byR/R0R1(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR7½s& "(R#R$R7(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRC»stDateFilterTestscB@seZd„ZRS(cC@sWtƒjƒ}tƒjƒjddƒ}|tjddƒ}tj|ƒ}tj j ddƒ}t j j d|d|d |ƒt j j d|d|d |ƒt j j d|d|d |ƒt j j d|d|d |ƒd t fd „ƒY}|i|d 6d t j j ƒƒ}|jt|jƒdƒ|j|jddgd„tƒdS(Nt microseconditdaysiR=ualextauthorttimetdateR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(udate(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"ës((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!êsudateR'iicS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*ñs(RRJRItreplacetdatetimet timedeltaRt text_typeRR,R-RRR.t assertEqualtlenR0R/R1(R2ttodayt timestampt last_weekt check_datetuR!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR7ßs"(R#R$R7(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyREÝstTimeFilterTestscB@seZd„ZRS(c C@srtƒjƒ}tƒjƒjddƒ}tƒtjddƒ}|jƒjddƒ}tj|ƒ}tj j ddƒ}t j j d|d|d |ƒt j j d|d|d |ƒt j j d|d|d |ƒt j j d|d|d |ƒd t fd „ƒY}|i|d 6d t j j ƒƒ}|jt|jƒdƒ|j|jddgd„tƒdS(NRFitminutesi R=ualexRHRIRJR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(utime(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!sutimeR'iicS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR* s(RRJRIRKRLRMRRNRR,R-RRR.RORPR0R/R1( R2RQtnow_timet ten_min_agot fixed_timet check_timeRUR!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR7ös"(R#R$R7(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRVôstDateTimeFilterTestscB@seZd„ZRS(c C@s”tƒ}|tjddƒ}|tjddƒ}tjjddƒ}tjjd|d|ƒtjjd|d|ƒtjjd|d|ƒtjƒ}tj ||ƒ}t j |ƒ}d t fd „ƒY}tjj ƒ} |i|d 6d | ƒ} |jt| jƒdƒ|j| jd gd„ƒ|i|d 6d | ƒ} |jt| jƒdd||fƒ|j| jd gd„ƒdS(NRWi RGiR=ualexRHt publishedR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(u published(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!su publishedR'icS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*$su!%s isn't matching %s when cleanedcS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*,s(RRLRMRR,R-RRtget_current_timezonet make_naiveRRNRR.RORPR0R/( R2tnow_dtRYt one_day_agoRUttztlocal_ten_min_agotcheck_dtR!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR7s*   (R#R$R7(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR\ stModelChoiceFilterTestscB@seZd„ZRS(cC@s tjjddƒ}tjjddƒ}tƒjƒ}tƒjƒ}tjjd|d|d|ƒtjjd|d|d|ƒtjjd|d|d|ƒdtfd„ƒY}tjjƒ}|i|j d 6d |ƒ}|j |j d d gd „t ƒdS(NR=ualexujacobRHRIRJR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(uauthor(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR";s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!:suauthorR'iicS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*As( RR,R-RRJRIRRR.R(R/R0R1(R2talextjacobRJRIR!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR71s(R#R$R7(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRe/stModelMultipleChoiceFilterTestscB@s5eZd„Zd„Zd„Zd„Zd„ZRS(cC@sêtjjddƒ}tjjddƒtjjddƒ}tjjddddd d ƒ}tjjdd ddd d ƒ}tjjdd ddd d ƒ}tjjdd ddd d ƒ||g|_||g|_||_dS(NR=ualexujacobuaaronRu Ender's GameRu1.00R g@u Rainbow Sixu SnowcrashuStranger in a Strage Land(RR,R-Rtfavorite_booksRf(R2RftaaronR3R4R5((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pytsetUpFs   cC@sdtfd„ƒY}tjjƒjdƒ}|idgd6d|ƒ}|j|jddgd „ƒ|idd gd6d|ƒ}|j|jddgd „ƒ|id gd6d|ƒ}|j|jdgd „ƒ|idgd6d|ƒ}|j|jgd„ƒdS(NR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(ufavorite_books(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Ys((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Xsuusernameu1ufavorite_booksR'uaaronualexcS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*_su3cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*bsu2cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*esu4cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*hs(RRR,R.RDR/R0(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR7WscC@sdtfd„ƒY}tjjƒjdƒ}|idgd6d|ƒ}|j|jddgd „ƒ|idd gd6d|ƒ}|j|jddgd „ƒ|id gd6d|ƒ}|j|jdgd „ƒ|idgd6d|ƒ}|j|jgd„ƒdS(NR!cB@seZddd„ƒYZRS(R"cB@seZeZidgd6ZRS(uexactufavorite_books(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"ls((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!ksuusernameu1ufavorite_booksR'uaaronualexcS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*rsu3cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*usu2cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*xsu4cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*{s(RRR,R.RDR/R0(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_filtering_dictionaryjsc@svdtf‡fd†ƒY‰tjjƒjdƒ}ˆiddgd6d|ƒ}|j|jdd gd „ƒdS( NR!c@s*eZddd„ƒYZ‡fd†ZRS(R"cB@seZeZdgZRS(ufavorite_books(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"sc@s`tˆ|ƒj||Ž|jdjjitjjdddgƒd6ƒt|jd_ dS(Nufavorite_bookstid__iniiuqueryset( tsupert__init__tfilterstextratupdateRR,tfilterR:trequired(R2targstkwargs(R!(sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRoƒs ((R#R$R"Ro((R!(sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!~suusernameu1u2ufavorite_booksR'uaaronualexcS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*’s(RRR,R.RDR/R0(R2R0R6((R!sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt*test_filtering_on_all_of_subset_of_choices}scC@sïdtfd„ƒY}tƒ}tjjd|d|jƒtjjd|d|jƒtjjd|ƒtjjƒ}gtjjƒD]}t|j ƒ^q‰}|i|d6d|ƒ}|j t |j ƒt tjj dtƒƒƒdS(NR!cB@s3eZedejjƒƒZddd„ƒYZRS(R'R"cB@seZeZdgZRS(uauthor(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"šs((R#R$RRR,R.RHR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!—sR]RHuauthorR'tauthor__isnull(RRRR,R-RfR.RtstrtidROtsetR0texcludeR:(R2R!R]R0tusertauthorsR6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt%test_filtering_on_non_required_fields”s ( (R#R$RkR7RlRwR(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRhDs     tNumberFilterTestscB@s5eZd„Zd„Zd„Zd„Zd„ZRS(cC@satjjddddddƒtjjdddddd ƒtjjdd dd dd ƒdS( NRu Ender's GameRu10.0R g333333@u Rainbow Sixu15.0gffffff@u Snowcrashu20.0g333333@(RR,R-(R2((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRkµs cC@sXdtfd„ƒY}|idd6dtjjƒƒ}|j|jdgd„ƒdS(NR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(uprice(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"¿s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!¾si upriceR'u Ender's GamecS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Äs(RRR,R.R/R0(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR7½s"cC@sddtfd„ƒY}|idd6dtjjƒjdƒƒ}|j|jddgd „ƒdS( NR!cB@s*eZeddƒZddd„ƒYZRS(t lookup_typeultR"cB@seZeZdgZRS(uprice(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Ês((R#R$RRR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!ÇsiupriceR'utitleu Ender's Gameu Rainbow SixcS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Ðs(RRR,R.RDR/R0(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt&test_filtering_with_single_lookup_typeÆs+cC@sddtfd„ƒY}|idd6dtjjƒjdƒƒ}|j|jddgd „ƒdS( NR!cB@seZddd„ƒYZRS(R"cB@seZeZidgd6ZRS(ultuprice(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Ôs((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Ósiu price__ltR'utitleu Ender's Gameu Rainbow SixcS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Ús(RRR,R.RDR/R0(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt1test_filtering_with_single_lookup_type_dictionaryÒs+cC@s"dtfd„ƒY}tjjƒ}|idd6dd6d|ƒ}|j|jdgd „ƒ|idd6dd6ƒ}|j|jdgd „ƒ|id d6dd6ƒ}|j|jdd d gd„dtƒdtfd„ƒY}|idd6ƒ}|j|jd gd„ƒdS(NR!cB@s0eZedddgƒZddd„ƒYZRS(RultugtR"cB@seZeZdgZRS(uprice(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"às((R#R$RRR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Ýsu15uprice_0ultuprice_1R'u Ender's GamecS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*æscS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*èsuu Rainbow Sixu SnowcrashcS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*ìsR+cB@s3eZeddddgƒZddd„ƒYZRS(RultugtuexactR"cB@seZeZdgZRS(uprice(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"ñs((R#R$RRR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!îscS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*ös(RRR,R.R/R0R1(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt)test_filtering_with_multiple_lookup_typesÜs   (R#R$RkR7R‚RƒR„(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR€³s   tRangeFilterTestscB@seZd„Zd„ZRS(cC@sŸtjjddddddƒtjjdddddd ƒtjjdd dd dd ƒtjjdd ddddƒtjjddddddƒdS(NRu Ender's GameRu10.0R g333333@u Rainbow Sixu15.0gffffff@u Snowcrashu20.0g333333@uRefundu-10.0g@u Free Booku0.0g(RR,R-(R2((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRkûscC@sØdtfd„ƒY}tjjƒjdƒ}|d|ƒ}|j|jddddd gd „ƒ|id d 6d d6d|ƒ}|j|jddgd„ƒ|idd 6d|ƒ}|j|jdd gd„ƒ|idd6d|ƒ}|j|jddddgd„ƒ|idd 6dd6d|ƒ}|j|jddgd„ƒ|idd 6dd6d|ƒ}|j|jddgd„ƒ|idd 6dd6d|ƒ}|j|jdgd„ƒdS(NR!cB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(uprice(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR" s((R#R$RRR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!s utitleR'u Ender's Gameu Free Booku Rainbow SixuRefundu SnowcrashcS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*su5uprice_0u15uprice_1cS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*su11cS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*su19cS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR* su0u12cS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*%su-11cS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*)scS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*-s(RRR,R.RDR/R0(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR7s<                     (R#R$RkR7(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR…ùs udate-range is funkytDateRangeFilterTestscB@s>eZd„Zd„Zd„Zejd„ƒZd„ZRS(cC@s*tƒjƒ}|tjddƒ}|tjddƒ}|tjddƒ}|tjddƒ}tjjddƒ}tƒjƒ}tjjd|d |d |ƒtjjd|d |d |ƒtjjd|d |d |ƒtjjd|d |d |ƒtjjd|d |d |ƒdS( NRGiii>i R=ualexRJRHRI( RRJRLRMRR,R-RIR(R2RQt five_days_agot two_weeks_agottwo_months_agot two_years_agoRfRI((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRk4scC@sUdtfd„ƒY}|idd6ƒ}|j|jddddgd „tƒdS( NR!cB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(udate(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Fs((R#R$R RJR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Cs u4udateiiiicS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Ks(RR/R0R1(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_filtering_for_yearBscC@sRdtfd„ƒY}|idd6ƒ}|j|jdddgd„tƒdS( NR!cB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(udate(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Qs((R#R$R RJR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Ns u3udateiiicS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Vs(RR/R0R1(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_filtering_for_monthMscC@sOdtfd„ƒY}|idd6ƒ}|j|jddgd„tƒdS(NR!cB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(udate(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"]s((R#R$R RJR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Zs u2udateiicS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*bs(RR/R0R1(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_filtering_for_weekXscC@sLdtfd„ƒY}|idd6ƒ}|j|jdgd„tƒdS(NR!cB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(udate(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"hs((R#R$R RJR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!es u1udateicS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*ms(RR/R0R1(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_filtering_for_todayds( R#R$RkR‹RŒRtexpectedFailureRRŽ(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR†1s    tAllValuesFilterTestscB@seZd„Zd„ZRS(cC@sÙtjjddƒtjjddƒtjjddƒdtfd„ƒY}|jt|ƒjƒttjjƒƒƒ|jt|idd6ƒƒtjjddƒgƒ|jt|idd6ƒƒtƒƒdS( NR=ualexujacobuaaronR!cB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(uusername(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"}s((R#R$RR=R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!zs uusernameujose( RR,R-RROtlistR0R.tget(R2R!((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR7us+cC@såtjjddƒtjjddƒtjjddƒdtfd„ƒY}|jt|ƒjƒttjjƒƒƒ|jt|idd6ƒƒtjjddƒgƒ|jt|idd6ƒƒttjjƒƒƒdS( NR=ualexujacobuaaronR!cB@s*eZeƒZeZddd„ƒYZRS(R"cB@seZeZdgZRS(uusername(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"s((R#R$RR=R1tstrictR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Œs uusernameujose( RR,R-RROR‘R0R.R’(R2R!((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_filtering_without_strict‡s+(R#R$R7R”(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRss tMethodFilterTestscB@s,eZd„Zd„Zd„Zd„ZRS(cC@sÙtjjddƒtjjddƒtjjddƒdtfd„ƒY}|jt|ƒjƒttjjƒƒƒ|jt|idd6ƒƒtjjddƒgƒ|jt|idd6ƒƒtƒƒdS( NR=ualexujacobuaaronR!cB@s3eZeddƒZddd„ƒYZd„ZRS(tactionufilter_usernameR"cB@seZeZdgZRS(uusername(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"¥scS@s|jd|ƒS(NR=(Rs(R2R'tvalue((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pytfilter_username©s ((R#R$R R=R"R˜(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!¢suusernameujose( RR,R-RROR‘R0R.R’(R2R!((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR7s +c@sètjjddƒtjjddƒtjjddƒd„‰dtf‡fd†ƒY}|jt|ƒjƒttjjƒƒƒ|jt|idd6ƒƒtjjddƒgƒ|jt|id d6ƒƒtƒƒdS( NR=ualexujacobuaaroncS@s|jd|ƒS(NR=(Rs(R'R—((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR˜¹s R!c@s*eZedˆƒZddd„ƒYZRS(R–R"cB@seZeZdgZRS(uusername(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Ás((R#R$R R=R"((R˜(sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!¾suusernameujose( RR,R-RROR‘R0R.R’(R2R!((R˜sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_filtering_external´s +cC@sStjjddƒtjjddƒtjjddƒdtfd„ƒY}|jt|ƒjƒttjjƒƒƒ|jt|idd6ƒƒtjjddƒtjjddƒgƒ|jt|idd6ƒƒtjjddƒtjjddƒgƒ|jt|idd6ƒƒtjjddƒtjjddƒgƒdS(NR=umikeujakeuaaronR!cB@s-eZeƒZddd„ƒYZd„ZRS(R"cB@seZeZdgZRS(uusername(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"ÔscS@s|jddƒS(Ntusername__containsuke(Rs(R2R'R—((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR˜Øs ((R#R$R R=R"R˜(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Ñs uusername( RR,R-RROR‘R0R.R’(R2R!((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt'test_filtering_default_attribute_actionÌs +cC@stjjddƒtjjddƒtjjddƒdtfd„ƒY}|jt|ƒjƒttjjƒƒƒ|jt|idd6ƒƒttjjƒƒƒ|jt|idd6ƒƒttjjƒƒƒ|jt|idd6ƒƒttjjƒƒƒdS(NR=umikeujakeuaaronR!cB@s-eZeƒZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(uusername(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"òs((R#R$R R=temailR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!îs  uusername(RR,R-RROR‘R0R.(R2R!((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_filtering_defaultés+(R#R$R7R™R›R(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR•›s   tO2ORelationshipTestscB@sPeZd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Z RS(cC@stjjdddtdtƒ}tjjdddtdtƒ}tjjdddtdtƒ}tjjdddtdtƒ}tjjd|d td tƒtjjd|d td tƒtjjd|d td tƒtjjd|d td tƒdS( Ntnameuaccount1tin_good_standingtfriendlyuaccount2uaccount3uaccount4taccountt likes_coffeet likes_tea(RR,R-R1R:R(R2ta1ta2ta3ta4((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRks    cC@s„dtfd„ƒY}|ƒ}|j|jjƒdƒ|idd6ƒ}|j|jjƒdƒ|j|jdgd„ƒdS(NR!cB@seZddd„ƒYZRS(R"cB@seZeZdZRS(uaccount(uaccount(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!siiuaccountcS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*s(RROR0tcountR/(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_o2o_relations  cC@s„dtfd„ƒY}|ƒ}|j|jjƒdƒ|idd6ƒ}|j|jjƒdƒ|j|jdgd„ƒdS(NR!cB@seZddd„ƒYZRS(R"cB@seZeZidgd6ZRS(uexactuaccount(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR" s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!siiuaccountcS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*)s(RROR0R©R/(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_o2o_relation_dictionarys  cC@s„dtfd„ƒY}|ƒ}|j|jjƒdƒ|idd6ƒ}|j|jjƒdƒ|j|jdgd„ƒdS(NR!cB@seZddd„ƒYZRS(R"cB@seZeZdZRS(uprofile(uprofile(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"-s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!,siiuprofilecS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*6s(RROR0R©R/(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_reverse_o2o_relation+s  cC@sŠdtfd„ƒY}|ƒ}|j|jjƒdƒ|idd6ƒ}|j|jjƒdƒ|j|jddgd„tƒdS( NR!cB@seZddd„ƒYZRS(R"cB@seZeZdZRS(uaccount__in_good_standing(uaccount__in_good_standing(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR":s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!9siu2uaccount__in_good_standingiicS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Cs(RROR0R©R/R1(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_o2o_relation_attribute8s  cC@s‹dtfd„ƒY}|ƒ}|j|jjƒdƒ|idd6dd6ƒ}|j|jjƒdƒ|j|jdgd „ƒdS( NR!cB@seZddd„ƒYZRS(R"cB@seZeZdZRS(uaccount__in_good_standinguaccount__friendly(uaccount__in_good_standinguaccount__friendly(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Gs((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Fsiu2uaccount__in_good_standinguaccount__friendlyiicS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Ps(RROR0R©R/(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_o2o_relation_attribute2Es  cC@sŠdtfd„ƒY}|ƒ}|j|jjƒdƒ|idd6ƒ}|j|jjƒdƒ|j|jddgd „tƒdS( NR!cB@seZddd„ƒYZRS(R"cB@seZeZdZRS(uprofile__likes_coffee(uprofile__likes_coffee(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Ts((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Ssiu2uprofile__likes_coffeeiiicS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*]s(RROR0R©R/R1(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt#test_reverse_o2o_relation_attributeRs  cC@s‹dtfd„ƒY}|ƒ}|j|jjƒdƒ|idd6dd6ƒ}|j|jjƒdƒ|j|jdgd „ƒdS( NR!cB@seZddd„ƒYZRS(R"cB@seZeZdZRS(uprofile__likes_coffeeuprofile__likes_tea(uprofile__likes_coffeeuprofile__likes_tea(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"as((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!`siu2uprofile__likes_coffeeuprofile__likes_teaiicS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*js(RROR0R©R/(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt$test_reverse_o2o_relation_attribute2_s  ( R#R$RkRªR«R¬R­R®R¯R°(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRžÿs    tFKRelationshipTestscB@sVeZd„Zd„Zd„Zd„Zejdƒd„ƒZej d„ƒZ RS(cC@stjjddƒ}tjjddƒ}tjjd|ddddƒtjjd|dd dd ƒtjjd|dd dd ƒd tfd„ƒY}|ƒ}|j|jjƒdƒ|idd6ƒ}|j|jjƒdƒ|j|jddgd„t ƒdS(NRŸucompany1ucompany2tcompanyt open_daysusometzip_codeu90210uWEEKENDu11111umondayu12345R!cB@seZddd„ƒYZRS(R"cB@seZeZdZRS(ucompany(ucompany(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"zs((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!ysiiucompanyicS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*ƒs( RR,R-RRROR0R©R/R1(R2tcompany1tcompany2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_fk_relationos    c C@sctjjddƒ}tjjddƒ}tƒjƒ}tƒjƒ}tjjddd|d|d|ƒtjjdd d|d|d|ƒtjjdd d|d|d|ƒd tfd „ƒY}tjjƒ}|id gd6d|ƒ}|j |j dgd„ƒd tfd„ƒY}|id d6d|ƒ}|j |j dgd„ƒdS(NR=ualexujacobttextu comment 1RHRIRJu comment 2u comment 3R!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(ucomments(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"’s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!‘siucommentsR'cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*˜scB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(ucomments(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"s((R#R$RtcommentsR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!šs cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*¢s( RR,R-RRJRIRRR.R/R0(R2RfRgRJRIR!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_reverse_fk_relation…s"cC@sOtƒ}tjjddƒ}tjjddƒ}tjjddƒtjjd|d|ƒtjjd|d|ƒtjjd|d|ƒdtfd„ƒY}|jt|jƒd gƒ|j|idd 6ƒj j ƒd ƒ|j|idd 6ƒj j ƒd ƒdtfd „ƒY}|j|idd 6ƒj j ƒd ƒdS( NR=ualexujacobuaaronRHR]R!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(uauthor__username(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"¯s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!®suauthor__usernameiicB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(uauthor__username(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"ºs((R#R$Rtauthor__usernameR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!·s ( RRR,R-RRROR‘t base_filtersR0R©(R2R`RfRgR!((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_fk_relation_attribute¤s &&c C@s`tjjddƒ}tjjddƒ}tƒjƒ}tƒjƒ}tjjddd|d|d|ƒtjjdd d|d|d|ƒtjjdd d|d|d|ƒd tfd „ƒY}tjjƒ}|id d 6d|ƒ}|j |j dgd„ƒd tfd„ƒY}|id d 6d|ƒ}|j |j dgd„ƒdS(NR=ualexujacobR¸u comment 1RHRIRJu comment 2u comment 3R!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(ucomments__text(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Ís((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Ìsucomments__textR'cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*ÓscB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(ucomments__text(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Øs((R#R$Rtcomments__textR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Õs cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Ýs( RR,R-RRJRIRRR.R/R0(R2RfRgRJRIR!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt"test_reverse_fk_relation_attributeÀs"utodo - need correct modelscC@sdS(N((R2((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt$test_fk_relation_multiple_attributesßscC@s tjjddƒ}tjjd|ddddƒtjjd|dddd ƒd tfd „ƒY}|idd 6dd 6ƒ}|j|jjƒdƒdS(NRŸucompanyR²R³usomeR´u90210uWEEKENDu11111R!cB@seZddd„ƒYZRS(R"cB@seZeZdZRS(ulocations__zip_codeulocations__open_days(ulocations__zip_codeulocations__open_days(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"ìs((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!ësulocations__zip_codeulocations__open_daysi(RR,R-RRROR0R©(R2R²R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt,test_reverse_fk_relation_multiple_attributesãs    ( R#R$R·RºR½R¿RtskipRÀRRÁ(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR±ms     tM2MRelationshipTestscB@s‰eZd„Zd„Zd„Zd„Zd„Zejd„ƒZ ejd„ƒZ ej dƒd„ƒZ ej dƒd „ƒZ RS( cC@sótjjddddƒ}tjjddddƒtjjddddƒ}tjjddd d d d ƒ}tjjdd d dd dƒ}tjjddd d d dƒ}tjjddd dd d ƒ||g|_||g|_dS(NR=ualexR@iujacobuaaronRu Ender's GameRu1.00R g@u Rainbow Sixu2.00g@u SnowcrashuStranger in a Strage Land(RR,R-RRi(R2RfRjR3R4R5((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRk÷s   cC@sdtfd„ƒY}tjjƒjdƒ}|idgd6d|ƒ}|j|jddgd „ƒ|idd gd6d|ƒ}|j|jddgd „ƒ|id gd6d|ƒ}|j|jdgd „ƒ|idgd6d|ƒ}|j|jgd„ƒdS(NR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(ufavorite_books(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!suusernameu1ufavorite_booksR'uaaronualexcS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*su3cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*su2cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*su4cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*s(RRR,R.RDR/R0(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_m2m_relationscC@s»dtfd„ƒY}tjjƒjdƒ}|idgd6d|ƒ}|j|jddgd „ƒdtfd „ƒY}|idd6d|ƒ}|j|jddgd „ƒdS( NR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(ulovers(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!sutitleiuloversR'u Ender's Gameu Rainbow SixcS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*"scB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(ulovers(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"'s((R#R$RtloversR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!$s cS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*-s(RRR,R.RDR/R0(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_reverse_m2m_relationscC@s,dtfd„ƒY}tjjƒjdƒ}|idd6d|ƒ}|j|jddgd „ƒ|id d6d|ƒ}|j|jdgd „ƒdtfd „ƒY}|ƒ}|jt|j dj j ƒd ƒdtfd„ƒY}|idd6d|ƒ}|j|jdgd„ƒdS(NR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(ufavorite_books__title(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"1s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!0suusernameu Ender's Gameufavorite_books__titleR'uaaronualexcS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*7su Rainbow SixcS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*:scB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(ufavorite_books__title(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"?s((R#R$R tfavorite_books__titleR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!<s icB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(ufavorite_books__title(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Ns((R#R$RRÇR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Ks u SnowcrashcS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Ss( RRR,R.RDR/R0RORPRptfieldRA(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_m2m_relation_attribute/s cC@s,dtfd„ƒY}tjjƒjdƒ}|idd6d|ƒ}|j|jddgd „ƒ|id d6d|ƒ}|j|jgd „ƒdtfd „ƒY}|ƒ}|jt|j dj j ƒd ƒdtfd„ƒY}|idd6d|ƒ}|j|jddgd„ƒdS(NR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(ulovers__username(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Ws((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Vsutitleualexulovers__usernameR'u Ender's Gameu Rainbow SixcS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*^sujacobcS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*ascB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(ulovers__username(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"fs((R#R$R tlovers__usernameR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!cs icB@s$eZeƒZddd„ƒYZRS(R"cB@seZeZdgZRS(ulovers__username(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"us((R#R$RRÊR"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!rs cS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*{s( RRR,R.RDR/R0RORPRpRÈRA(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt#test_reverse_m2m_relation_attributeUs cC@s§dtfd„ƒY}tjjƒjdƒ}|idd6dd6d|ƒ}|j|jd gd „ƒ|id d6dd6d|ƒ}|j|jgd „ƒdS( NR!cB@seZddd„ƒYZRS(R"cB@seZeZddgZRS(ufavorite_books__priceufavorite_books__average_rating(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"€s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!suusernameu1.00ufavorite_books__priceg@ufavorite_books__average_ratingR'uaaroncS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*‰su3.00cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Žs(RRR,R.RDR/R0(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt%test_m2m_relation_multiple_attributes}s      cC@sªdtfd„ƒY}tjjƒjdƒ}|idd6dd6d|ƒ}|j|jd d gd „ƒ|idd6d d6d|ƒ}|j|jgd „ƒdS(NR!cB@seZddd„ƒYZRS(R"cB@seZeZddgZRS(ulovers__statusulovers__username(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"“s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!’sutitleiulovers__statusualexulovers__usernameR'u Ender's Gameu Rainbow SixcS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*šsujacobcS@s|jS(N(R(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*s(RRR,R.RDR/R0(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt-test_reverse_m2m_relation_multiple_attributess  utodocC@sdS(N((R2((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt test_fk_relation_on_m2m_relationŸscC@sdS(N((R2((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt*test_fk_relation_attribute_on_m2m_relation£s(R#R$RkRÄRÆRÉRËRRRÌRÍRÂRÎRÏ(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRÃõs    & (t+SymmetricalSelfReferentialRelationshipTestscB@seZd„Zd„ZRS(cC@s˜tjjddƒ}tjjddƒ}tjjddƒ}tjjddƒ}|jj|ƒ|jj|ƒ|jj|ƒ|jj|ƒdS(NRŸuoneutwouthreeufour(RR,R-t adjacentstadd(R2tn1tn2tn3tn4((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRkªscC@smdtfd„ƒY}tjjƒjdƒ}|idgd6d|ƒ}|j|jddgd „ƒdS( NR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(u adjacents(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"¶s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!µsupku1u adjacentsR'iicS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*¼s(RRR,R.RDR/R0(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt test_relation´s(R#R$RkR×(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRШs t.NonSymmetricalSelfReferentialRelationshipTestscB@s#eZd„Zd„Zd„ZRS(cC@s˜tjjddƒ}tjjddƒ}tjjddƒ}tjjddƒ}|jj|ƒ|jj|ƒ|jj|ƒ|jj|ƒdS(NRŸuoneutwouthreeufour(RR,R-toutbound_nodesRÒ(R2RÓRÔRÕRÖ((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRkÁscC@sjdtfd„ƒY}tjjƒjdƒ}|idgd6d|ƒ}|j|jdgd„ƒdS( NR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(uoutbound_nodes(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"Ís((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Ìsupku1uoutbound_nodesR'icS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Ós(RRR,R.RDR/R0(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_forward_relationËscC@sjdtfd„ƒY}tjjƒjdƒ}|idgd6d|ƒ}|j|jdgd„ƒdS( NR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(u inbound_nodes(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"×s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!Ösupku1u inbound_nodesR'icS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*Ýs(RRR,R.RDR/R0(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_reverse_relationÕs(R#R$RkRÚRÛ(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRØ¿s tMiscFilterSetTestscB@s>eZd„Zd„Zd„Zd„Zd„Zd„ZRS(cC@shtjjddddƒtjjddddƒtjjddddƒtjjdddd ƒdS( NR=ualexR@iujacobiuaaronucarli(RR,R-(R2((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRkâscC@sqdtfd„ƒY}tjƒ}|idd6d|ƒ}|j}|j||ƒ|jjjjddƒdS(NR!cB@s*eZeddƒZddd„ƒYZRS(RŸuusernameR"cB@seZeZdgZRS(uaccount(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"ìs((R#R$R R¢R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!ésujdoeuaccountR'tusername__exact( Rtmockt MagicMockR0tassertNotEqualR.t return_valueRstassert_called_with(R2R!R0R6tresult((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt$test_filtering_with_declared_filtersès   cC@sždtfd„ƒY}tjjƒ}|idd6dd6d|ƒ}|j|jdgd„ƒ|idd6d d6d|ƒ}|j|jgd „ƒdS( NR!cB@seZddd„ƒYZRS(R"cB@seZeZddgZRS(ustatusuusername(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"øs((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!÷sualexuusernameu1ustatusR'cS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*ÿsu2cS@s|jS(N(R((R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*s(RRR,R.R/R0(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt$test_filtering_with_multiple_filtersös   cC@s^dtfd„ƒY}|idd6dtjjƒƒ}|j|jddgd„tƒdS( NR!cB@s-eZedd„ƒZddd„ƒYZRS(R–cS@s|ji|d6S(Nuusername__startswith(Rs(R0R—((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*sR"cB@seZeZdgZRS(uusername(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR" s((R#R$R R=R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!suauusernameR'ualexuaaroncS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*s(RRR,R.R/R0R1(R2R!R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_filter_with_actions"cC@s‰dtfd„ƒY}tjjƒ}|d|ƒ}|j|jdgd„ƒ|idd6d|ƒ}|j|jdgd „ƒdS( NR!cB@s0eZededdƒZddd„ƒYZRS(RAtinitialiR"cB@seZeZdgZRS(ustatus(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR"s((R#R$R RR@R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!sR'ualexcS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*siustatusucarlcS@s|jS(N(R=(R)((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR*s(RRR,R.R/R0(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyttest_filter_with_initials cC@s?dtfd„ƒY}tjjƒ}|d|ƒ}|jt|jƒdƒ|j|jƒdƒ|idd6d|ƒ}|jt|jƒdƒ|j|jƒdƒ|idd6d|ƒ}|jt|jƒdƒ|j|jƒdƒ|id d6d|ƒ}|jt|jƒd ƒ|j|jƒd ƒdS( NR!cB@seZddd„ƒYZRS(R"cB@seZeZdgZRS(ustatus(R#R$RR%R&(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR""s((R#R$R"(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyR!!sR'iu0ustatusiu1u2i(RRR,R.RORPR0R©(R2R!R0R6((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyt test_qs_count s(R#R$RkRäRåRæRèRé(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pyRÜàs     (ii(>t __future__RRRLRÞtsyst version_infoRt django.utilst django.testRRtdjango.utils.timezoneRRtdjango_filters.filtersetRtdjango_filters.filtersRR R R R R RRRtmodelsRRRRRRRRRRRRRR8R<R?RCRERVR\ReRhR€R…RÂR†RR•RžR±RÃRÐRØRÜ(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filtering.pytsn   ="#oF8A(dnˆ³!django-filter-0.11.0/tests/test_filters.py0000644000076500000240000006310712563340337021343 0ustar carltonstaff00000000000000from __future__ import absolute_import from __future__ import unicode_literals from datetime import date, datetime, time import mock import sys if sys.version_info >= (2, 7): import unittest else: # pragma: nocover from django.utils import unittest # noqa from datetime import timedelta from django import forms from django.test import TestCase from django_filters.fields import ( Lookup, RangeField, DateRangeField, TimeRangeField, LookupTypeField) from django_filters.filters import ( Filter, CharFilter, BooleanFilter, ChoiceFilter, MultipleChoiceFilter, DateFilter, DateTimeFilter, TimeFilter, ModelChoiceFilter, ModelMultipleChoiceFilter, NumberFilter, NumericRangeFilter, RangeFilter, DateRangeFilter, DateFromToRangeFilter, TimeRangeFilter, AllValuesFilter, LOOKUP_TYPES) from tests.models import Book, User class FilterTests(TestCase): def test_creation(self): f = Filter() self.assertEqual(f.lookup_type, 'exact') self.assertEqual(f.exclude, False) def test_creation_order(self): f = Filter() f2 = Filter() self.assertTrue(f2.creation_counter > f.creation_counter) def test_default_field(self): f = Filter() field = f.field self.assertIsInstance(field, forms.Field) self.assertEqual(field.help_text, 'Filter') def test_field_with_exclusion(self): f = Filter(exclude=True) field = f.field self.assertIsInstance(field, forms.Field) self.assertEqual(field.help_text, 'This is an exclusion filter') 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_lookup_type_and_exlusion(self): f = Filter(lookup_type=None, exclude=True) field = f.field self.assertIsInstance(field, LookupTypeField) self.assertEqual(field.help_text, 'This is an exclusion filter') 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', spec=['__call__']) as mocked: f = Filter(name='somefield', label='somelabel', widget='somewidget') f.field mocked.assert_called_once_with(required=False, label='somelabel', widget='somewidget', help_text=mock.ANY) def test_field_extra_params(self): with mock.patch.object(Filter, 'field_class', spec=['__call__']) as mocked: f = Filter(someattr='someattr') f.field mocked.assert_called_once_with(required=mock.ANY, label=mock.ANY, widget=mock.ANY, help_text=mock.ANY, someattr='someattr') def test_field_with_required_filter(self): with mock.patch.object(Filter, 'field_class', spec=['__call__']) as mocked: f = Filter(required=True) f.field mocked.assert_called_once_with(required=True, label=mock.ANY, widget=mock.ANY, help_text=mock.ANY) def test_filtering(self): qs = mock.Mock(spec=['filter']) f = Filter() result = f.filter(qs, 'value') qs.filter.assert_called_once_with(None__exact='value') self.assertNotEqual(qs, result) def test_filtering_exclude(self): qs = mock.Mock(spec=['filter', 'exclude']) f = Filter(exclude=True) result = f.filter(qs, 'value') qs.exclude.assert_called_once_with(None__exact='value') self.assertNotEqual(qs, result) def test_filtering_uses_name(self): qs = mock.Mock(spec=['filter']) f = Filter(name='somefield') f.filter(qs, 'value') result = qs.filter.assert_called_once_with(somefield__exact='value') self.assertNotEqual(qs, result) def test_filtering_skipped_with_blank_value(self): qs = mock.Mock() f = Filter() result = f.filter(qs, '') self.assertListEqual(qs.method_calls, []) self.assertEqual(qs, result) def test_filtering_skipped_with_none_value(self): qs = mock.Mock() f = Filter() result = f.filter(qs, None) self.assertListEqual(qs.method_calls, []) self.assertEqual(qs, result) def test_filtering_with_list_value(self): qs = mock.Mock(spec=['filter']) f = Filter(name='somefield', lookup_type=['some_lookup_type']) result = f.filter(qs, Lookup('value', 'some_lookup_type')) qs.filter.assert_called_once_with(somefield__some_lookup_type='value') self.assertNotEqual(qs, result) def test_filtering_skipped_with_list_value_with_blank(self): qs = mock.Mock() f = Filter(name='somefield', lookup_type=['some_lookup_type']) result = f.filter(qs, Lookup('', 'some_lookup_type')) self.assertListEqual(qs.method_calls, []) self.assertEqual(qs, result) def test_filtering_skipped_with_list_value_with_blank_lookup(self): return # Now field is required to provide valid lookup_type if it provides any qs = mock.Mock(spec=['filter']) f = Filter(name='somefield', lookup_type=None) result = f.filter(qs, Lookup('value', '')) qs.filter.assert_called_once_with(somefield__exact='value') self.assertNotEqual(qs, result) def test_filter_using_action(self): qs = mock.NonCallableMock(spec=[]) action = mock.Mock(spec=['filter']) f = Filter(action=action) result = f.filter(qs, 'value') action.assert_called_once_with(qs, 'value') self.assertNotEqual(qs, result) def test_filtering_uses_distinct(self): qs = mock.Mock(spec=['filter', 'distinct']) f = Filter(name='somefield', distinct=True) f.filter(qs, 'value') result = qs.distinct.assert_called_once() self.assertNotEqual(qs, result) class CharFilterTests(TestCase): def test_default_field(self): f = CharFilter() field = f.field self.assertIsInstance(field, forms.CharField) class BooleanFilterTests(TestCase): def test_default_field(self): f = BooleanFilter() field = f.field self.assertIsInstance(field, forms.NullBooleanField) def test_filtering(self): qs = mock.Mock(spec=['filter']) f = BooleanFilter(name='somefield') result = f.filter(qs, True) qs.filter.assert_called_once_with(somefield=True) self.assertNotEqual(qs, result) def test_filtering_exclude(self): qs = mock.Mock(spec=['exclude']) f = BooleanFilter(name='somefield', exclude=True) result = f.filter(qs, True) qs.exclude.assert_called_once_with(somefield=True) self.assertNotEqual(qs, result) @unittest.expectedFailure def test_filtering_skipped_with_blank_value(self): qs = mock.Mock() f = BooleanFilter(name='somefield') result = f.filter(qs, '') self.assertListEqual(qs.method_calls, []) self.assertEqual(qs, result) def test_filtering_skipped_with_none_value(self): qs = mock.Mock() f = BooleanFilter(name='somefield') result = f.filter(qs, None) self.assertListEqual(qs.method_calls, []) self.assertEqual(qs, result) class ChoiceFilterTests(TestCase): def test_default_field(self): f = ChoiceFilter() field = f.field self.assertIsInstance(field, forms.ChoiceField) class MultipleChoiceFilterTests(TestCase): def test_default_field(self): f = MultipleChoiceFilter() field = f.field self.assertIsInstance(field, forms.MultipleChoiceField) def test_filtering_requires_name(self): qs = mock.Mock(spec=['filter']) f = MultipleChoiceFilter() with self.assertRaises(TypeError): f.filter(qs, ['value']) def test_conjoined_default_value(self): f = MultipleChoiceFilter() self.assertFalse(f.conjoined) def test_conjoined_true(self): f = MultipleChoiceFilter(conjoined=True) self.assertTrue(f.conjoined) def test_filtering(self): qs = mock.Mock(spec=['filter']) f = MultipleChoiceFilter(name='somefield') with mock.patch('django_filters.filters.Q') as mockQclass: mockQ1, mockQ2 = mock.MagicMock(), mock.MagicMock() mockQclass.side_effect = [mockQ1, mockQ2] f.filter(qs, ['value']) self.assertEqual(mockQclass.call_args_list, [mock.call(), mock.call(somefield='value')]) mockQ1.__ior__.assert_called_once_with(mockQ2) qs.filter.assert_called_once_with(mockQ1.__ior__.return_value) qs.filter.return_value.distinct.assert_called_once_with() def test_filtering_exclude(self): qs = mock.Mock(spec=['exclude']) f = MultipleChoiceFilter(name='somefield', exclude=True) with mock.patch('django_filters.filters.Q') as mockQclass: mockQ1, mockQ2 = mock.MagicMock(), mock.MagicMock() mockQclass.side_effect = [mockQ1, mockQ2] f.filter(qs, ['value']) self.assertEqual(mockQclass.call_args_list, [mock.call(), mock.call(somefield='value')]) mockQ1.__ior__.assert_called_once_with(mockQ2) qs.exclude.assert_called_once_with(mockQ1.__ior__.return_value) qs.exclude.return_value.distinct.assert_called_once_with() def test_filtering_on_required_skipped_when_len_of_value_is_len_of_field_choices(self): qs = mock.Mock(spec=[]) f = MultipleChoiceFilter(name='somefield', required=True) f.always_filter = False result = f.filter(qs, []) self.assertEqual(len(f.field.choices), 0) self.assertEqual(qs, result) f.field.choices = ['some', 'values', 'here'] result = f.filter(qs, ['some', 'values', 'here']) self.assertEqual(qs, result) result = f.filter(qs, ['other', 'values', 'there']) self.assertEqual(qs, result) @unittest.expectedFailure def test_filtering_skipped_with_empty_list_value_and_some_choices(self): qs = mock.Mock(spec=[]) f = MultipleChoiceFilter(name='somefield') f.field.choices = ['some', 'values', 'here'] result = f.filter(qs, []) self.assertEqual(qs, result) def test_filter_conjoined_true(self): """Tests that a filter with `conjoined=True` returns objects that have all the values included in `value`. For example filter users that have all of this books. """ book_kwargs = {'price': 1, 'average_rating': 1} books = [] books.append(Book.objects.create(**book_kwargs)) books.append(Book.objects.create(**book_kwargs)) books.append(Book.objects.create(**book_kwargs)) books.append(Book.objects.create(**book_kwargs)) books.append(Book.objects.create(**book_kwargs)) books.append(Book.objects.create(**book_kwargs)) user1 = User.objects.create() user2 = User.objects.create() user3 = User.objects.create() user4 = User.objects.create() user5 = User.objects.create() user1.favorite_books.add(books[0], books[1]) user2.favorite_books.add(books[0], books[1], books[2]) user3.favorite_books.add(books[1], books[2]) user4.favorite_books.add(books[2], books[3]) user5.favorite_books.add(books[4], books[5]) filter_list = ( ((books[0].pk, books[0].pk), # values [1, 2]), # list of user.pk that have `value` books ((books[1].pk, books[1].pk), [1, 2, 3]), ((books[2].pk, books[2].pk), [2, 3, 4]), ((books[3].pk, books[3].pk), [4, ]), ((books[4].pk, books[4].pk), [5, ]), ((books[0].pk, books[1].pk), [1, 2]), ((books[0].pk, books[2].pk), [2, ]), ((books[1].pk, books[2].pk), [2, 3]), ((books[2].pk, books[3].pk), [4, ]), ((books[4].pk, books[5].pk), [5, ]), ((books[3].pk, books[4].pk), []), ) users = User.objects.all() for item in filter_list: f = MultipleChoiceFilter(name='favorite_books__pk', conjoined=True) queryset = f.filter(users, item[0]) expected_pks = [c[0] for c in queryset.values_list('pk')] self.assertListEqual( expected_pks, item[1], 'Lists Differ: {0} != {1} for case {2}'.format( expected_pks, item[1], item[0])) class DateFilterTests(TestCase): def test_default_field(self): f = DateFilter() field = f.field self.assertIsInstance(field, forms.DateField) class DateTimeFilterTests(TestCase): def test_default_field(self): f = DateTimeFilter() field = f.field self.assertIsInstance(field, forms.DateTimeField) class TimeFilterTests(TestCase): def test_default_field(self): f = TimeFilter() field = f.field self.assertIsInstance(field, forms.TimeField) class ModelChoiceFilterTests(TestCase): def test_default_field_without_queryset(self): f = ModelChoiceFilter() with self.assertRaises(TypeError): f.field def test_default_field_with_queryset(self): qs = mock.NonCallableMock(spec=[]) f = ModelChoiceFilter(queryset=qs) field = f.field self.assertIsInstance(field, forms.ModelChoiceField) self.assertEqual(field.queryset, qs) class ModelMultipleChoiceFilterTests(TestCase): def test_default_field_without_queryset(self): f = ModelMultipleChoiceFilter() with self.assertRaises(TypeError): f.field def test_default_field_with_queryset(self): qs = mock.NonCallableMock(spec=[]) f = ModelMultipleChoiceFilter(queryset=qs) field = f.field self.assertIsInstance(field, forms.ModelMultipleChoiceField) self.assertEqual(field.queryset, qs) class NumberFilterTests(TestCase): def test_default_field(self): f = NumberFilter() field = f.field self.assertIsInstance(field, forms.DecimalField) def test_filtering(self): qs = mock.Mock(spec=['filter']) f = NumberFilter() f.filter(qs, 1) qs.filter.assert_called_once_with(None__exact=1) # Also test 0 as it once had a bug qs.reset_mock() f.filter(qs, 0) qs.filter.assert_called_once_with(None__exact=0) def test_filtering_exclude(self): qs = mock.Mock(spec=['exclude']) f = NumberFilter(exclude=True) f.filter(qs, 1) qs.exclude.assert_called_once_with(None__exact=1) # Also test 0 as it once had a bug qs.reset_mock() f.filter(qs, 0) qs.exclude.assert_called_once_with(None__exact=0) class NumericRangeFilterTests(TestCase): def test_default_field(self): f = NumericRangeFilter() field = f.field self.assertIsInstance(field, RangeField) def test_filtering(self): qs = mock.Mock(spec=['filter']) value = mock.Mock(start=20, stop=30) f = NumericRangeFilter() f.filter(qs, value) qs.filter.assert_called_once_with(None__exact=(20, 30)) def test_filtering_exclude(self): qs = mock.Mock(spec=['exclude']) value = mock.Mock(start=20, stop=30) f = NumericRangeFilter(exclude=True) f.filter(qs, value) qs.exclude.assert_called_once_with(None__exact=(20, 30)) def test_filtering_skipped_with_none_value(self): qs = mock.Mock(spec=['filter']) f = NumericRangeFilter() result = f.filter(qs, None) self.assertEqual(qs, result) def test_field_with_lookup_type(self): qs = mock.Mock() value = mock.Mock(start=20, stop=30) f = NumericRangeFilter(lookup_type=('overlap')) f.filter(qs, value) qs.filter.assert_called_once_with(None__overlap=(20, 30)) @unittest.expectedFailure def test_filtering_lower_field_higher_than_upper_field(self): qs = mock.Mock(spec=['filter']) value = mock.Mock(start=35, stop=30) f = NumericRangeFilter() result = f.filter(qs, value) self.assertEqual(qs, result) def test_zero_to_zero(self): qs = mock.Mock(spec=['filter']) value = mock.Mock(start=0, stop=0) f = NumericRangeFilter() f.filter(qs, value) qs.filter.assert_called_once_with(None__exact=(0, 0)) class RangeFilterTests(TestCase): def test_default_field(self): f = RangeFilter() field = f.field self.assertIsInstance(field, RangeField) def test_filtering_range(self): qs = mock.Mock(spec=['filter']) value = mock.Mock(start=20, stop=30) f = RangeFilter() f.filter(qs, value) qs.filter.assert_called_once_with(None__range=(20, 30)) def test_filtering_exclude(self): qs = mock.Mock(spec=['exclude']) value = mock.Mock(start=20, stop=30) f = RangeFilter(exclude=True) f.filter(qs, value) qs.exclude.assert_called_once_with(None__range=(20, 30)) def test_filtering_start(self): qs = mock.Mock(spec=['filter']) value = mock.Mock(start=20, stop=None) f = RangeFilter() f.filter(qs, value) qs.filter.assert_called_once_with(None__gte=20) def test_filtering_stop(self): qs = mock.Mock(spec=['filter']) value = mock.Mock(start=None, stop=30) f = RangeFilter() f.filter(qs, value) qs.filter.assert_called_once_with(None__lte=30) def test_filtering_skipped_with_none_value(self): qs = mock.Mock(spec=['filter']) f = RangeFilter() result = f.filter(qs, None) self.assertEqual(qs, result) def test_filtering_ignores_lookup_type(self): qs = mock.Mock() value = mock.Mock(start=20, stop=30) f = RangeFilter(lookup_type='gte') f.filter(qs, value) qs.filter.assert_called_once_with(None__range=(20, 30)) class DateRangeFilterTests(TestCase): def test_creating(self): f = DateRangeFilter() self.assertIn('choices', f.extra) self.assertEqual(len(DateRangeFilter.options), len(f.extra['choices'])) def test_default_field(self): f = DateRangeFilter() field = f.field self.assertIsInstance(field, forms.ChoiceField) def test_filtering(self): qs = mock.Mock(spec=['all']) f = DateRangeFilter() f.filter(qs, '') qs.all.assert_called_once_with() # the correct behavior fails right now @unittest.expectedFailure def test_filtering_skipped_with_blank_value(self): qs = mock.Mock(spec=[]) f = DateRangeFilter() result = f.filter(qs, '') self.assertEqual(qs, result) @unittest.expectedFailure def test_filtering_skipped_with_out_of_range_value(self): qs = mock.Mock(spec=[]) f = DateRangeFilter() result = f.filter(qs, 999) self.assertEqual(qs, result) def test_filtering_for_this_year(self): qs = mock.Mock(spec=['filter']) with mock.patch('django_filters.filters.now') as mock_now: now_dt = mock_now.return_value f = DateRangeFilter() f.filter(qs, '4') qs.filter.assert_called_once_with( None__year=now_dt.year) def test_filtering_for_this_month(self): qs = mock.Mock(spec=['filter']) with mock.patch('django_filters.filters.now') as mock_now: now_dt = mock_now.return_value f = DateRangeFilter() f.filter(qs, '3') qs.filter.assert_called_once_with( None__year=now_dt.year, None__month=now_dt.month) def test_filtering_for_7_days(self): qs = mock.Mock(spec=['filter']) with mock.patch('django_filters.filters.now'): with mock.patch('django_filters.filters.timedelta') as mock_td: with mock.patch( 'django_filters.filters._truncate') as mock_truncate: mock_dt1, mock_dt2 = mock.MagicMock(), mock.MagicMock() mock_truncate.side_effect = [mock_dt1, mock_dt2] f = DateRangeFilter() f.filter(qs, '2') self.assertEqual(mock_td.call_args_list, [mock.call(days=7), mock.call(days=1)]) qs.filter.assert_called_once_with( None__lt=mock_dt2, None__gte=mock_dt1) def test_filtering_for_today(self): qs = mock.Mock(spec=['filter']) with mock.patch('django_filters.filters.now') as mock_now: now_dt = mock_now.return_value f = DateRangeFilter() f.filter(qs, '1') qs.filter.assert_called_once_with( None__year=now_dt.year, None__month=now_dt.month, None__day=now_dt.day) def test_filtering_for_yesterday(self): qs = mock.Mock(spec=['filter']) with mock.patch('django_filters.filters.now') as mock_now: now_dt = mock_now.return_value f = DateRangeFilter() f.filter(qs, '5') qs.filter.assert_called_once_with( None__year=now_dt.year, None__month=now_dt.month, None__day=(now_dt - timedelta(days=1)).day, ) class DateFromToRangeFilterTests(TestCase): def test_default_field(self): f = DateFromToRangeFilter() field = f.field self.assertIsInstance(field, DateRangeField) def test_filtering_range(self): qs = mock.Mock(spec=['filter']) value = mock.Mock(start=date(2015, 4, 7), stop=date(2015, 9, 6)) f = DateFromToRangeFilter() f.filter(qs, value) qs.filter.assert_called_once_with( None__range=(date(2015, 4, 7), date(2015, 9, 6))) def test_filtering_start(self): qs = mock.Mock(spec=['filter']) value = mock.Mock(start=date(2015, 4, 7), stop=None) f = DateFromToRangeFilter() f.filter(qs, value) qs.filter.assert_called_once_with(None__gte=date(2015, 4, 7)) def test_filtering_stop(self): qs = mock.Mock(spec=['filter']) value = mock.Mock(start=None, stop=date(2015, 9, 6)) f = DateFromToRangeFilter() f.filter(qs, value) qs.filter.assert_called_once_with(None__lte=date(2015, 9, 6)) def test_filtering_skipped_with_none_value(self): qs = mock.Mock(spec=['filter']) f = DateFromToRangeFilter() result = f.filter(qs, None) self.assertEqual(qs, result) def test_filtering_ignores_lookup_type(self): qs = mock.Mock() value = mock.Mock(start=date(2015, 4, 7), stop=date(2015, 9, 6)) f = DateFromToRangeFilter(lookup_type='gte') f.filter(qs, value) qs.filter.assert_called_once_with( None__range=(date(2015, 4, 7), date(2015, 9, 6))) class TimeRangeFilterTests(TestCase): def test_default_field(self): f = TimeRangeFilter() field = f.field self.assertIsInstance(field, TimeRangeField) def test_filtering_range(self): qs = mock.Mock(spec=['filter']) value = mock.Mock(start=time(10, 15), stop=time(12, 30)) f = TimeRangeFilter() f.filter(qs, value) qs.filter.assert_called_once_with( None__range=(time(10, 15), time(12, 30))) def test_filtering_start(self): qs = mock.Mock(spec=['filter']) value = mock.Mock(start=time(10, 15), stop=None) f = TimeRangeFilter() f.filter(qs, value) qs.filter.assert_called_once_with(None__gte=time(10, 15)) def test_filtering_stop(self): qs = mock.Mock(spec=['filter']) value = mock.Mock(start=None, stop=time(12, 30)) f = TimeRangeFilter() f.filter(qs, value) qs.filter.assert_called_once_with(None__lte=time(12, 30)) def test_filtering_skipped_with_none_value(self): qs = mock.Mock(spec=['filter']) f = TimeRangeFilter() result = f.filter(qs, None) self.assertEqual(qs, result) def test_filtering_ignores_lookup_type(self): qs = mock.Mock() value = mock.Mock(start=time(10, 15), stop=time(12, 30)) f = TimeRangeFilter(lookup_type='gte') f.filter(qs, value) qs.filter.assert_called_once_with( None__range=(time(10, 15), time(12, 30))) class AllValuesFilterTests(TestCase): def test_default_field_without_assigning_model(self): f = AllValuesFilter() with self.assertRaises(AttributeError): f.field def test_default_field_with_assigning_model(self): mocked = mock.Mock() chained_call = '.'.join(['_default_manager', 'distinct.return_value', 'order_by.return_value', 'values_list.return_value']) mocked.configure_mock(**{chained_call: iter([])}) f = AllValuesFilter() f.model = mocked field = f.field self.assertIsInstance(field, forms.ChoiceField) django-filter-0.11.0/tests/test_filters.pyc0000644000076500000240000011210012562714615021475 0ustar carltonstaff00000000000000ó ª—ËUc@@sàddlmZddlmZddlmZmZmZddlZddlZejd0krrddl Z nddl m Z ddlm Z dd l m Z dd lmZdd lmZmZmZmZmZdd lmZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(dd l)m*Z*m+Z+defd„ƒYZ,defd„ƒYZ-defd„ƒYZ.defd„ƒYZ/defd„ƒYZ0defd„ƒYZ1defd„ƒYZ2defd„ƒYZ3defd„ƒYZ4d efd!„ƒYZ5d"efd#„ƒYZ6d$efd%„ƒYZ7d&efd'„ƒYZ8d(efd)„ƒYZ9d*efd+„ƒYZ:d,efd-„ƒYZ;d.efd/„ƒYZ<dS(1i(tabsolute_import(tunicode_literals(tdatetdatetimettimeNii(tunittest(t timedelta(tforms(tTestCase(tLookupt RangeFieldtDateRangeFieldtTimeRangeFieldtLookupTypeField(tFiltert CharFiltert BooleanFiltert ChoiceFiltertMultipleChoiceFiltert DateFiltertDateTimeFiltert TimeFiltertModelChoiceFiltertModelMultipleChoiceFiltert NumberFiltertNumericRangeFiltert RangeFiltertDateRangeFiltertDateFromToRangeFiltertTimeRangeFiltertAllValuesFiltert LOOKUP_TYPES(tBooktUsert FilterTestscB@sÅeZd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z d „Z d „Z d „Z d „Zd „Zd„Zd„Zd„Zd„Zd„Zd„Zd„ZRS(cC@s3tƒ}|j|jdƒ|j|jtƒdS(Nuexact(Rt assertEqualt lookup_typetexcludetFalse(tselftf((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt test_creation2s cC@s/tƒ}tƒ}|j|j|jkƒdS(N(Rt assertTruetcreation_counter(R'R(tf2((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_creation_order7s  cC@s<tƒ}|j}|j|tjƒ|j|jdƒdS(NuFilter(RtfieldtassertIsInstanceRtFieldR#t help_text(R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_default_field<s  cC@sBtdtƒ}|j}|j|tjƒ|j|jdƒdS(NR%uThis is an exclusion filter(RtTrueR.R/RR0R#R1(R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_field_with_exclusionBs cC@s/tddƒ}|j}|j|tjƒdS(NR$uiexact(RR.R/RR0(R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt"test_field_with_single_lookup_typeHs cC@sXtddƒ}|j}|j|tƒ|jd}|jt|jƒtt ƒƒdS(NR$i( RtNoneR.R/R tfieldsR#tlentchoicesR(R'R(R.t choice_field((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt test_field_with_none_lookup_typeMs   cC@sEtdddtƒ}|j}|j|tƒ|j|jdƒdS(NR$R%uThis is an exclusion filter(RR6R3R.R/R R#R1(R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt(test_field_with_lookup_type_and_exlusionTs cC@sRtddƒ}|j}|j|tƒ|jd}|jt|jƒdƒdS(NR$u istartswithu iendswithii(u istartswithu iendswith(RR.R/R R7R#R8R9(R'R(R.R:((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt test_field_with_list_lookup_typeZs   c C@srtjjtdddgƒN}tdddddd ƒ}|j|jd tdddd d tjƒWdQXdS( Nu field_classtspecu__call__tnameu somefieldtlabelu somelabeltwidgetu somewidgettrequiredR1(tmocktpatchtobjectRR.tassert_called_once_withR&tANY(R'tmockedR(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_field_paramsas cC@sutjjtdddgƒQ}tddƒ}|j|jdtjdtjdtjd tjddƒWdQXdS( Nu field_classR>u__call__tsomeattrusomeattrRBR@RAR1(RCRDRERR.RFRG(R'RHR(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_field_extra_paramsjsc C@sltjjtdddgƒH}tdtƒ}|j|jdtdtjdtjdtjƒWdQXdS(Nu field_classR>u__call__RBR@RAR1(RCRDRERR3R.RFRG(R'RHR(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_field_with_required_filterss cC@sWtjddgƒ}tƒ}|j|dƒ}|jjddƒ|j||ƒdS(NR>ufilteruvaluet None__exact(RCtMockRtfilterRFtassertNotEqual(R'tqsR(tresult((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering{s  cC@s`tjdddgƒ}tdtƒ}|j|dƒ}|jjddƒ|j||ƒdS(NR>ufilteruexcludeR%uvalueRM(RCRNRR3ROR%RFRP(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering_exclude‚s cC@s]tjddgƒ}tddƒ}|j|dƒ|jjddƒ}|j||ƒdS(NR>ufilterR?u somefielduvaluetsomefield__exact(RCRNRRORFRP(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering_uses_name‰s cC@sNtjƒ}tƒ}|j|dƒ}|j|jgƒ|j||ƒdS(Nu(RCRNRROtassertListEqualt method_callsR#(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt'test_filtering_skipped_with_blank_values   cC@sNtjƒ}tƒ}|j|dƒ}|j|jgƒ|j||ƒdS(N(RCRNRROR6RWRXR#(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt&test_filtering_skipped_with_none_value—s   cC@sotjddgƒ}tddddgƒ}|j|tddƒƒ}|jjddƒ|j||ƒdS( NR>ufilterR?u somefieldR$usome_lookup_typeuvaluetsomefield__some_lookup_type(RCRNRROR RFRP(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering_with_list_valuežs cC@sftjƒ}tddddgƒ}|j|tddƒƒ}|j|jgƒ|j||ƒdS(NR?u somefieldR$usome_lookup_typeu(RCRNRROR RWRXR#(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt1test_filtering_skipped_with_list_value_with_blank¥s  cC@sldStjddgƒ}tdddtƒ}|j|tddƒƒ}|jjddƒ|j||ƒ( NR>ufilterR?u somefieldR$uvalueuRU(RCRNRR6ROR RFRP(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt8test_filtering_skipped_with_list_value_with_blank_lookup¬s cC@sltjdgƒ}tjddgƒ}td|ƒ}|j|dƒ}|j|dƒ|j||ƒdS(NR>ufiltertactionuvalue(RCtNonCallableMockRNRRORFRP(R'RQR_R(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filter_using_action´s cC@s`tjdddgƒ}tdddtƒ}|j|dƒ|jjƒ}|j||ƒdS(NR>ufilterudistinctR?u somefieldtdistinctuvalue(RCRNRR3RORbtassert_called_onceRP(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering_uses_distinct¼s (t__name__t __module__R)R-R2R4R5R;R<R=RIRKRLRSRTRVRYRZR\R]R^RaRd(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR"0s*                  tCharFilterTestscB@seZd„ZRS(cC@s)tƒ}|j}|j|tjƒdS(N(RR.R/Rt CharField(R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR2Æs  (ReRfR2(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRgÄstBooleanFilterTestscB@s>eZd„Zd„Zd„Zejd„ƒZd„ZRS(cC@s)tƒ}|j}|j|tjƒdS(N(RR.R/RtNullBooleanField(R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR2Îs  cC@s]tjddgƒ}tddƒ}|j|tƒ}|jjdtƒ|j||ƒdS(NR>ufilterR?u somefieldt somefield(RCRNRROR3RFRP(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRSÓs cC@sctjddgƒ}tdddtƒ}|j|tƒ}|jjdtƒ|j||ƒdS(NR>uexcludeR?u somefieldR%Rk(RCRNRR3ROR%RFRP(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRTÚs cC@sTtjƒ}tddƒ}|j|dƒ}|j|jgƒ|j||ƒdS(NR?u somefieldu(RCRNRRORWRXR#(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRYás  cC@sTtjƒ}tddƒ}|j|dƒ}|j|jgƒ|j||ƒdS(NR?u somefield(RCRNRROR6RWRXR#(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRZés  ( ReRfR2RSRTRtexpectedFailureRYRZ(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRiÌs    tChoiceFilterTestscB@seZd„ZRS(cC@s)tƒ}|j}|j|tjƒdS(N(RR.R/Rt ChoiceField(R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR2ós  (ReRfR2(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRmñstMultipleChoiceFilterTestscB@sbeZd„Zd„Zd„Zd„Zd„Zd„Zd„Ze j d„ƒZ d„Z RS( cC@s)tƒ}|j}|j|tjƒdS(N(RR.R/RtMultipleChoiceField(R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR2ûs  cC@sKtjddgƒ}tƒ}|jtƒ|j|dgƒWdQXdS(NR>ufilteruvalue(RCRNRt assertRaisest TypeErrorRO(R'RQR(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering_requires_names cC@stƒ}|j|jƒdS(N(Rt assertFalset conjoined(R'R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_conjoined_default_values cC@s#tdtƒ}|j|jƒdS(NRu(RR3R*Ru(R'R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_conjoined_true sc C@sßtjddgƒ}tddƒ}tjdƒ¦}tjƒtjƒ}}||g|_|j|dgƒ|j|jtj ƒtj ddƒgƒ|j j |ƒ|jj |j j ƒ|jj j j ƒWdQXdS(NR>ufilterR?u somefieldudjango_filters.filters.QuvalueRk(RCRNRRDt MagicMockt side_effectROR#tcall_args_listtcallt__ior__RFt return_valueRb(R'RQR(t mockQclasstmockQ1tmockQ2((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRSs c C@såtjddgƒ}tdddtƒ}tjdƒ¦}tjƒtjƒ}}||g|_|j|dgƒ|j|j tj ƒtj ddƒgƒ|j j |ƒ|j j |j jƒ|j jjj ƒWdQXdS( NR>uexcludeR?u somefieldR%udjango_filters.filters.QuvalueRk(RCRNRR3RDRxRyROR#RzR{R|RFR%R}Rb(R'RQR(R~RR€((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRTs cC@sÝtjdgƒ}tdddtƒ}t|_|j|gƒ}|jt|j j ƒdƒ|j||ƒdddg|j _ |j|dddgƒ}|j||ƒ|j|d dd gƒ}|j||ƒdS( NR>R?u somefieldRBiusomeuvaluesuhereuotheruthere( RCRNRR3R&t always_filterROR#R8R.R9(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pytLtest_filtering_on_required_skipped_when_len_of_value_is_len_of_field_choices,s cC@s\tjdgƒ}tddƒ}dddg|j_|j|gƒ}|j||ƒdS(NR>R?u somefieldusomeuvaluesuhere(RCRNRR.R9ROR#(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt=test_filtering_skipped_with_empty_list_value_and_some_choices;s c C@s¤idd6dd6}g}|jtjj|ƒ|jtjj|ƒ|jtjj|ƒ|jtjj|ƒ|jtjj|ƒ|jtjj|ƒtjjƒ}tjjƒ}tjjƒ}tjjƒ}tjjƒ}|jj|d|dƒ|jj|d|d|dƒ|jj|d|dƒ|jj|d|dƒ|jj|d|dƒ|dj|djfddgf|dj|djfdddgf|dj|djfdddgf|dj|djfdgf|dj|djfdgf|dj|djfddgf|dj|djfdgf|dj|djfddgf|dj|djfdgf|dj|djfdgf|dj|djfgff }tjjƒ} x|D]…} t d d d t ƒ} | j | | dƒ} g| j d ƒD]} | d^qX}|j || dd j|| d| dƒƒqWdS(u·Tests that a filter with `conjoined=True` returns objects that have all the values included in `value`. For example filter users that have all of this books. iupriceuaverage_ratingiiiiiR?ufavorite_books__pkRuupku%Lists Differ: {0} != {1} for case {2}N(tappendR tobjectstcreateR!tfavorite_bookstaddtpktallRR3ROt values_listRWtformat(R't book_kwargstbookstuser1tuser2tuser3tuser4tuser5t filter_listtuserstitemR(tquerysettct expected_pks((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filter_conjoined_trueCsd"          &( ReRfR2RsRvRwRSRTR‚RRlRƒRš(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRoùs       tDateFilterTestscB@seZd„ZRS(cC@s)tƒ}|j}|j|tjƒdS(N(RR.R/Rt DateField(R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR2…s  (ReRfR2(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR›ƒstDateTimeFilterTestscB@seZd„ZRS(cC@s)tƒ}|j}|j|tjƒdS(N(RR.R/Rt DateTimeField(R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR2s  (ReRfR2(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR‹stTimeFilterTestscB@seZd„ZRS(cC@s)tƒ}|j}|j|tjƒdS(N(RR.R/Rt TimeField(R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR2•s  (ReRfR2(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRŸ“stModelChoiceFilterTestscB@seZd„Zd„ZRS(cC@s*tƒ}|jtƒ |jWdQXdS(N(RRqRrR.(R'R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt#test_default_field_without_querysets cC@sTtjdgƒ}td|ƒ}|j}|j|tjƒ|j|j|ƒdS(NR>R—( RCR`RR.R/RtModelChoiceFieldR#R—(R'RQR(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt test_default_field_with_queryset¢s  (ReRfR¢R¤(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR¡›s tModelMultipleChoiceFilterTestscB@seZd„Zd„ZRS(cC@s*tƒ}|jtƒ |jWdQXdS(N(RRqRrR.(R'R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR¢¬s cC@sTtjdgƒ}td|ƒ}|j}|j|tjƒ|j|j|ƒdS(NR>R—( RCR`RR.R/RtModelMultipleChoiceFieldR#R—(R'RQR(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR¤±s  (ReRfR¢R¤(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR¥ªs tNumberFilterTestscB@s#eZd„Zd„Zd„ZRS(cC@s)tƒ}|j}|j|tjƒdS(N(RR.R/Rt DecimalField(R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR2»s  cC@srtjddgƒ}tƒ}|j|dƒ|jjddƒ|jƒ|j|dƒ|jjddƒdS(NR>ufilteriRMi(RCRNRRORFt reset_mock(R'RQR(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRSÀs  cC@sxtjddgƒ}tdtƒ}|j|dƒ|jjddƒ|jƒ|j|dƒ|jjddƒdS(NR>uexcludeR%iRMi(RCRNRR3ROR%RFR©(R'RQR(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRTÊs (ReRfR2RSRT(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR§¹s  tNumericRangeFilterTestscB@sPeZd„Zd„Zd„Zd„Zd„Zejd„ƒZ d„Z RS(cC@s&tƒ}|j}|j|tƒdS(N(RR.R/R (R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR2×s  cC@s]tjddgƒ}tjddddƒ}tƒ}|j||ƒ|jjddƒdS( NR>ufiltertstartitstopiRM(ii(RCRNRRORF(R'RQtvalueR(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRSÜs  cC@sctjddgƒ}tjddddƒ}tdtƒ}|j||ƒ|jjdd ƒdS( NR>uexcludeR«iR¬iR%RM(ii(RCRNRR3ROR%RF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRTãs cC@sDtjddgƒ}tƒ}|j|dƒ}|j||ƒdS(NR>ufilter(RCRNRROR6R#(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRZês cC@sZtjƒ}tjddddƒ}tddƒ}|j||ƒ|jjddƒdS( NR«iR¬iR$uoverlapt None__overlap(ii(RCRNRRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_field_with_lookup_typeðs  cC@s\tjddgƒ}tjddddƒ}tƒ}|j||ƒ}|j||ƒdS(NR>ufilterR«i#R¬i(RCRNRROR#(R'RQR­R(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt2test_filtering_lower_field_higher_than_upper_field÷s  cC@s]tjddgƒ}tjddddƒ}tƒ}|j||ƒ|jjddƒdS(NR>ufilterR«iR¬RM(ii(RCRNRRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_zero_to_zeroÿs  ( ReRfR2RSRTRZR¯RRlR°R±(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRªÕs     tRangeFilterTestscB@sGeZd„Zd„Zd„Zd„Zd„Zd„Zd„ZRS(cC@s&tƒ}|j}|j|tƒdS(N(RR.R/R (R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR2 s  cC@s]tjddgƒ}tjddddƒ}tƒ}|j||ƒ|jjddƒdS( NR>ufilterR«iR¬it None__range(ii(RCRNRRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering_ranges  cC@sctjddgƒ}tjddddƒ}tdtƒ}|j||ƒ|jjdd ƒdS( NR>uexcludeR«iR¬iR%R³(ii(RCRNRR3ROR%RF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRTs cC@s]tjddgƒ}tjddddƒ}tƒ}|j||ƒ|jjddƒdS(NR>ufilterR«iR¬t None__gte(RCRNR6RRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering_starts  cC@s]tjddgƒ}tjddddƒ}tƒ}|j||ƒ|jjddƒdS(NR>ufilterR«R¬it None__lte(RCRNR6RRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering_stop#s  cC@sDtjddgƒ}tƒ}|j|dƒ}|j||ƒdS(NR>ufilter(RCRNRROR6R#(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRZ*s cC@sZtjƒ}tjddddƒ}tddƒ}|j||ƒ|jjddƒdS( NR«iR¬iR$ugteR³(ii(RCRNRRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt"test_filtering_ignores_lookup_type0s  ( ReRfR2R´RTR¶R¸RZR¹(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR²s      tDateRangeFilterTestscB@steZd„Zd„Zd„Zejd„ƒZejd„ƒZd„Z d„Z d„Z d„Z d „Z RS( cC@sFtƒ}|jd|jƒ|jttjƒt|jdƒƒdS(Nuchoices(RtassertIntextraR#R8toptions(R'R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt test_creating:s cC@s)tƒ}|j}|j|tjƒdS(N(RR.R/RRn(R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR2?s  cC@s?tjddgƒ}tƒ}|j|dƒ|jjƒdS(NR>uallu(RCRNRRORŠRF(R'RQR(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRSDs cC@sAtjdgƒ}tƒ}|j|dƒ}|j||ƒdS(NR>u(RCRNRROR#(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRYKs cC@sAtjdgƒ}tƒ}|j|dƒ}|j||ƒdS(NR>iç(RCRNRROR#(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt.test_filtering_skipped_with_out_of_range_valueRs cC@sitjddgƒ}tjdƒ?}|j}tƒ}|j|dƒ|jjd|jƒWdQXdS(NR>ufilterudjango_filters.filters.nowu4t None__year(RCRNRDR}RRORFtyear(R'RQtmock_nowtnow_dtR(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering_for_this_yearYs   c C@srtjddgƒ}tjdƒH}|j}tƒ}|j|dƒ|jjd|jd|jƒWdQXdS(NR>ufilterudjango_filters.filters.nowu3RÀt None__month( RCRNRDR}RRORFRÁtmonth(R'RQRÂRÃR(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering_for_this_monthbs   cC@sêtjddgƒ}tjdƒÀtjdƒª}tjdƒ’}tjƒtjƒ}}||g|_tƒ}|j|dƒ|j|jtj ddƒtj dd ƒgƒ|jj d |d |ƒWdQXWdQXWdQXdS( NR>ufilterudjango_filters.filters.nowu django_filters.filters.timedeltau django_filters.filters._truncateu2tdaysiitNone__ltRµ( RCRNRDRxRyRROR#RzR{RF(R'RQtmock_tdt mock_truncatetmock_dt1tmock_dt2R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering_for_7_daysks   % c C@s{tjddgƒ}tjdƒQ}|j}tƒ}|j|dƒ|jjd|jd|jd|j ƒWdQXdS(NR>ufilterudjango_filters.filters.nowu1RÀRÅt None__day( RCRNRDR}RRORFRÁRÆtday(R'RQRÂRÃR(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering_for_todayzs     cC@sˆtjddgƒ}tjdƒ^}|j}tƒ}|j|dƒ|jjd|jd|jd|t dd ƒj ƒWdQXdS( NR>ufilterudjango_filters.filters.nowu5RÀRÅRÏRÈi( RCRNRDR}RRORFRÁRÆRRÐ(R'RQRÂRÃR(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyttest_filtering_for_yesterday…s     (ReRfR¾R2RSRRlRYR¿RÄRÇRÎRÑRÒ(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRº8s     tDateFromToRangeFilterTestscB@s>eZd„Zd„Zd„Zd„Zd„Zd„ZRS(cC@s&tƒ}|j}|j|tƒdS(N(RR.R/R (R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR2”s  cC@s“tjddgƒ}tjdtdddƒdtddd ƒƒ}tƒ}|j||ƒ|jjd tdddƒtddd ƒfƒdS( NR>ufilterR«ißiiR¬i iR³(RCRNRRRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR´™s 0  cC@sutjddgƒ}tjdtdddƒddƒ}tƒ}|j||ƒ|jjdtdddƒƒdS( NR>ufilterR«ißiiR¬Rµ(RCRNRR6RRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR¶¡s $ cC@sutjddgƒ}tjdddtdddƒƒ}tƒ}|j||ƒ|jjdtdddƒƒdS( NR>ufilterR«R¬ißi iR·(RCRNR6RRRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR¸¨s $ cC@sDtjddgƒ}tƒ}|j|dƒ}|j||ƒdS(NR>ufilter(RCRNRROR6R#(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRZ¯s cC@stjƒ}tjdtdddƒdtdddƒƒ}tdd ƒ}|j||ƒ|jjd tdddƒtdddƒfƒdS( NR«ißiiR¬i iR$ugteR³(RCRNRRRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR¹µs  0 (ReRfR2R´R¶R¸RZR¹(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRÓ’s      tTimeRangeFilterTestscB@s>eZd„Zd„Zd„Zd„Zd„Zd„ZRS(cC@s&tƒ}|j}|j|tƒdS(N(RR.R/R (R'R(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR2Às  cC@s‡tjddgƒ}tjdtddƒdtddƒƒ}tƒ}|j||ƒ|jjd tddƒtddƒfƒdS( NR>ufilterR«i iR¬i iR³(RCRNRRRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR´Ås *  cC@sotjddgƒ}tjdtddƒddƒ}tƒ}|j||ƒ|jjdtddƒƒdS(NR>ufilterR«i iR¬Rµ(RCRNRR6RRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR¶Ís ! cC@sotjddgƒ}tjdddtddƒƒ}tƒ}|j||ƒ|jjdtddƒƒdS(NR>ufilterR«R¬i iR·(RCRNR6RRRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR¸Ôs ! cC@sDtjddgƒ}tƒ}|j|dƒ}|j||ƒdS(NR>ufilter(RCRNRROR6R#(R'RQR(RR((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRZÛs cC@s„tjƒ}tjdtddƒdtddƒƒ}tddƒ}|j||ƒ|jjd tddƒtddƒfƒdS( NR«i iR¬i iR$ugteR³(RCRNRRRORF(R'RQR­R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyR¹ás  * (ReRfR2R´R¶R¸RZR¹(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRÔ¾s      tAllValuesFilterTestscB@seZd„Zd„ZRS(cC@s*tƒ}|jtƒ |jWdQXdS(N(RRqtAttributeErrorR.(R'R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt*test_default_field_without_assigning_modelìs cC@sstjƒ}djddddgƒ}|jitgƒ|6tƒ}||_|j}|j|t j ƒdS(Nu.u_default_managerudistinct.return_valueuorder_by.return_valueuvalues_list.return_value( RCRNtjointconfigure_mocktiterRtmodelR.R/RRn(R'RHt chained_callR(R.((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyt'test_default_field_with_assigning_modelñs     (ReRfR×RÝ(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyRÕês (ii(=t __future__RRRRRRCtsyst version_infoRt django.utilsRtdjangoRt django.testRtdjango_filters.fieldsR R R R R tdjango_filters.filtersRRRRRRRRRRRRRRRRRRt tests.modelsR R!R"RgRiRmRoR›RRŸR¡R¥R§RªR²RºRÓRÔRÕ(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filters.pyts<  (v”%Š21Z,,django-filter-0.11.0/tests/test_filterset.py0000644000076500000240000005553212524657704021705 0ustar carltonstaff00000000000000from __future__ import absolute_import, unicode_literals import mock import sys if sys.version_info >= (2, 7): import unittest else: # pragma: nocover from django.utils import unittest # noqa from django.db import models from django.test import TestCase from django_filters.filterset import FilterSet from django_filters.filterset import FILTER_FOR_DBFIELD_DEFAULTS from django_filters.filterset import get_model_field from django_filters.filters import CharFilter from django_filters.filters import NumberFilter from django_filters.filters import ChoiceFilter from django_filters.filters import ModelChoiceFilter from django_filters.filters import ModelMultipleChoiceFilter from .models import User from .models import AdminUser from .models import Book from .models import Profile from .models import Comment from .models import Restaurant from .models import NetworkSetting from .models import SubnetMaskField from .models import Account from .models import BankAccount from .models import Node from .models import DirectedNode from .models import Worker from .models import HiredWorker from .models import Business def checkItemsEqual(L1, L2): """ TestCase.assertItemsEqual() is not available in Python 2.6. """ return len(L1) == len(L2) and sorted(L1) == sorted(L2) class HelperMethodsTests(TestCase): @unittest.skip('todo') def test_get_declared_filters(self): pass def test_get_model_field_none(self): result = get_model_field(User, 'unknown__name') self.assertIsNone(result) def test_get_model_field(self): result = get_model_field(Business, 'hiredworker__worker') self.assertEqual(result, HiredWorker._meta.get_field('worker')) @unittest.skip('todo') def test_filters_for_model(self): pass @unittest.skip('todo') def test_filterset_factory(self): pass class DbFieldDefaultFiltersTests(TestCase): def test_expected_db_fields_get_filters(self): to_check = [ models.BooleanField, models.CharField, models.CommaSeparatedIntegerField, models.DateField, models.DateTimeField, models.DecimalField, models.EmailField, models.FilePathField, models.FloatField, models.IntegerField, models.IPAddressField, models.NullBooleanField, models.PositiveIntegerField, models.PositiveSmallIntegerField, models.SlugField, models.SmallIntegerField, models.TextField, models.TimeField, models.URLField, models.ForeignKey, models.OneToOneField, models.ManyToManyField, ] msg = "%s expected to be found in FILTER_FOR_DBFIELD_DEFAULTS" for m in to_check: self.assertIn(m, FILTER_FOR_DBFIELD_DEFAULTS, msg % m.__name__) def test_expected_db_fields_do_not_get_filters(self): to_check = [ models.Field, models.BigIntegerField, models.GenericIPAddressField, models.FileField, models.ImageField, ] msg = "%s expected to not be found in FILTER_FOR_DBFIELD_DEFAULTS" for m in to_check: self.assertNotIn(m, FILTER_FOR_DBFIELD_DEFAULTS, msg % m.__name__) class FilterSetFilterForFieldTests(TestCase): def test_filter_found_for_field(self): f = User._meta.get_field('username') result = FilterSet.filter_for_field(f, 'username') self.assertIsInstance(result, CharFilter) self.assertEqual(result.name, 'username') def test_filter_found_for_autofield(self): f = User._meta.get_field('id') result = FilterSet.filter_for_field(f, 'id') self.assertIsInstance(result, NumberFilter) self.assertEqual(result.name, 'id') def test_field_with_extras(self): 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']) self.assertEqual(result.extra['queryset'].model, Book) def test_field_with_choices(self): 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_field_that_is_subclassed(self): f = User._meta.get_field('first_name') result = FilterSet.filter_for_field(f, 'first_name') self.assertIsInstance(result, CharFilter) def test_symmetrical_selfref_m2m_field(self): f = Node._meta.get_field('adjacents') result = FilterSet.filter_for_field(f, 'adjacents') self.assertIsInstance(result, ModelMultipleChoiceFilter) self.assertEqual(result.name, 'adjacents') self.assertTrue('queryset' in result.extra) self.assertIsNotNone(result.extra['queryset']) self.assertEqual(result.extra['queryset'].model, Node) def test_non_symmetrical_selfref_m2m_field(self): f = DirectedNode._meta.get_field('outbound_nodes') result = FilterSet.filter_for_field(f, 'outbound_nodes') self.assertIsInstance(result, ModelMultipleChoiceFilter) self.assertEqual(result.name, 'outbound_nodes') self.assertTrue('queryset' in result.extra) self.assertIsNotNone(result.extra['queryset']) self.assertEqual(result.extra['queryset'].model, DirectedNode) def test_m2m_field_with_through_model(self): f = Business._meta.get_field('employees') result = FilterSet.filter_for_field(f, 'employees') self.assertIsInstance(result, ModelMultipleChoiceFilter) self.assertEqual(result.name, 'employees') self.assertTrue('queryset' in result.extra) self.assertIsNotNone(result.extra['queryset']) self.assertEqual(result.extra['queryset'].model, Worker) @unittest.skip('todo') def test_filter_overrides(self): pass class FilterSetFilterForReverseFieldTests(TestCase): def test_reverse_o2o_relationship(self): f = Account._meta.get_field_by_name('profile')[0] result = FilterSet.filter_for_reverse_field(f, 'profile') self.assertIsInstance(result, ModelChoiceFilter) self.assertEqual(result.name, 'profile') self.assertTrue('queryset' in result.extra) self.assertIsNotNone(result.extra['queryset']) self.assertEqual(result.extra['queryset'].model, Profile) def test_reverse_fk_relationship(self): f = User._meta.get_field_by_name('comments')[0] result = FilterSet.filter_for_reverse_field(f, 'comments') self.assertIsInstance(result, ModelMultipleChoiceFilter) self.assertEqual(result.name, 'comments') self.assertTrue('queryset' in result.extra) self.assertIsNotNone(result.extra['queryset']) self.assertEqual(result.extra['queryset'].model, Comment) def test_reverse_m2m_relationship(self): f = Book._meta.get_field_by_name('lovers')[0] result = FilterSet.filter_for_reverse_field(f, 'lovers') self.assertIsInstance(result, ModelMultipleChoiceFilter) self.assertEqual(result.name, 'lovers') self.assertTrue('queryset' in result.extra) self.assertIsNotNone(result.extra['queryset']) self.assertEqual(result.extra['queryset'].model, User) def test_reverse_non_symmetrical_selfref_m2m_field(self): f = DirectedNode._meta.get_field_by_name('inbound_nodes')[0] result = FilterSet.filter_for_reverse_field(f, 'inbound_nodes') self.assertIsInstance(result, ModelMultipleChoiceFilter) self.assertEqual(result.name, 'inbound_nodes') self.assertTrue('queryset' in result.extra) self.assertIsNotNone(result.extra['queryset']) self.assertEqual(result.extra['queryset'].model, DirectedNode) def test_reverse_m2m_field_with_through_model(self): f = Worker._meta.get_field_by_name('employers')[0] result = FilterSet.filter_for_reverse_field(f, 'employers') self.assertIsInstance(result, ModelMultipleChoiceFilter) self.assertEqual(result.name, 'employers') self.assertTrue('queryset' in result.extra) self.assertIsNotNone(result.extra['queryset']) self.assertEqual(result.extra['queryset'].model, Business) class FilterSetClassCreationTests(TestCase): def test_no_filters(self): class F(FilterSet): pass self.assertEqual(len(F.declared_filters), 0) self.assertEqual(len(F.base_filters), 0) def test_declaring_filter(self): class F(FilterSet): username = CharFilter() self.assertEqual(len(F.declared_filters), 1) self.assertListEqual(list(F.declared_filters), ['username']) self.assertEqual(len(F.base_filters), 1) self.assertListEqual(list(F.base_filters), ['username']) def test_model_derived(self): class F(FilterSet): class Meta: model = Book self.assertEqual(len(F.declared_filters), 0) self.assertEqual(len(F.base_filters), 3) self.assertListEqual(list(F.base_filters), ['title', 'price', 'average_rating']) def test_declared_and_model_derived(self): class F(FilterSet): username = CharFilter() class Meta: model = Book self.assertEqual(len(F.declared_filters), 1) self.assertEqual(len(F.base_filters), 4) self.assertListEqual(list(F.base_filters), ['title', 'price', 'average_rating', 'username']) def test_meta_fields_with_declared_and_model_derived(self): class F(FilterSet): username = CharFilter() class Meta: model = Book fields = ('username', 'price') self.assertEqual(len(F.declared_filters), 1) self.assertEqual(len(F.base_filters), 2) self.assertListEqual(list(F.base_filters), ['username', 'price']) def test_meta_fields_dictionary_derived(self): class F(FilterSet): class Meta: model = Book fields = {'price': ['exact', 'gte', 'lte'], } self.assertEqual(len(F.declared_filters), 0) self.assertEqual(len(F.base_filters), 3) expected_list = ['price', 'price__gte', 'price__lte', ] self.assertTrue(checkItemsEqual(list(F.base_filters), expected_list)) def test_meta_fields_containing_autofield(self): class F(FilterSet): username = CharFilter() class Meta: model = Book fields = ('id', 'username', 'price') self.assertEqual(len(F.declared_filters), 1) self.assertEqual(len(F.base_filters), 3) self.assertListEqual(list(F.base_filters), ['id', 'username', 'price']) def test_meta_fields_dictionary_autofield(self): class F(FilterSet): username = CharFilter() class Meta: model = Book fields = {'id': ['exact'], 'username': ['exact'], } self.assertEqual(len(F.declared_filters), 1) self.assertEqual(len(F.base_filters), 2) expected_list = ['id', 'username'] self.assertTrue(checkItemsEqual(list(F.base_filters), expected_list)) def test_meta_fields_containing_unknown(self): with self.assertRaises(TypeError): class F(FilterSet): username = CharFilter() class Meta: model = Book fields = ('username', 'price', 'other') def test_meta_fields_dictionary_containing_unknown(self): with self.assertRaises(TypeError): class F(FilterSet): class Meta: model = Book fields = {'id': ['exact'], 'title': ['exact'], 'other': ['exact'], } def test_meta_exlude_with_declared_and_declared_wins(self): class F(FilterSet): username = CharFilter() class Meta: model = Book exclude = ('username', 'price') self.assertEqual(len(F.declared_filters), 1) self.assertEqual(len(F.base_filters), 3) self.assertListEqual(list(F.base_filters), ['title', 'average_rating', 'username']) def test_meta_fields_and_exlude_and_exclude_wins(self): class F(FilterSet): username = CharFilter() class Meta: model = Book fields = ('username', 'title', 'price') exclude = ('title',) self.assertEqual(len(F.declared_filters), 1) self.assertEqual(len(F.base_filters), 2) self.assertListEqual(list(F.base_filters), ['username', 'price']) def test_filterset_class_inheritance(self): class F(FilterSet): class Meta: model = Book class G(F): pass self.assertEqual(set(F.base_filters), set(G.base_filters)) class F(FilterSet): other = CharFilter class Meta: model = Book class G(F): pass self.assertEqual(set(F.base_filters), set(G.base_filters)) def test_abstract_model_inheritance(self): class F(FilterSet): class Meta: model = Restaurant self.assertEqual(set(F.base_filters), set(['name', 'serves_pizza'])) class F(FilterSet): class Meta: model = Restaurant fields = ['name', 'serves_pizza'] self.assertEqual(set(F.base_filters), set(['name', 'serves_pizza'])) def test_custom_field_ignored(self): class F(FilterSet): class Meta: model = NetworkSetting self.assertEqual(list(F.base_filters.keys()), ['ip']) def test_custom_field_gets_filter_from_override(self): class F(FilterSet): filter_overrides = { SubnetMaskField: {'filter_class': CharFilter}} class Meta: model = NetworkSetting self.assertEqual(list(F.base_filters.keys()), ['ip', 'mask']) def test_filterset_for_proxy_model(self): class F(FilterSet): class Meta: model = User class ProxyF(FilterSet): class Meta: model = AdminUser self.assertEqual(list(F.base_filters), list(ProxyF.base_filters)) @unittest.expectedFailure def test_filterset_for_mti_model(self): class F(FilterSet): class Meta: model = Account class FtiF(FilterSet): class Meta: model = BankAccount # fails due to 'account_ptr' getting picked up self.assertEqual( list(F.base_filters) + ['amount_saved'], list(FtiF.base_filters)) class FilterSetInstantiationTests(TestCase): def test_creating_instance(self): class F(FilterSet): class Meta: model = User fields = ['username'] f = F() 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): class Meta: model = User fields = ['username'] f = F({'username': 'username'}) self.assertTrue(f.is_bound) def test_creating_with_queryset(self): class F(FilterSet): class Meta: model = User fields = ['username'] m = mock.Mock() f = F(queryset=m) self.assertEqual(f.queryset, m) class FilterSetOrderingTests(TestCase): def setUp(self): self.alex = User.objects.create(username='alex', status=1) self.jacob = User.objects.create(username='jacob', status=2) self.aaron = User.objects.create(username='aaron', status=2) self.carl = User.objects.create(username='carl', status=0) # user_ids = list(User.objects.all().values_list('pk', flat=True)) self.qs = User.objects.all().order_by('id') def test_ordering_when_unbound(self): class F(FilterSet): class Meta: model = User fields = ['username', 'status'] order_by = ['status'] f = F(queryset=self.qs) self.assertQuerysetEqual( f.qs, ['carl', 'alex', 'jacob', 'aaron'], lambda o: o.username) def test_ordering(self): class F(FilterSet): class Meta: model = User fields = ['username', 'status'] order_by = ['username', 'status'] f = F({'o': 'username'}, queryset=self.qs) self.assertQuerysetEqual( f.qs, ['aaron', 'alex', 'carl', 'jacob'], lambda o: o.username) f = F({'o': 'status'}, queryset=self.qs) self.assertQuerysetEqual( f.qs, ['carl', 'alex', 'jacob', 'aaron'], lambda o: o.username) def test_ordering_on_unknown_value(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, [], lambda o: o.username) def test_ordering_on_unknown_value_results_in_default_ordering_without_strict(self): class F(FilterSet): strict = False 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_different_field(self): class F(FilterSet): class Meta: model = User fields = ['username', 'status'] order_by = True f = F({'o': 'username'}, queryset=self.qs) self.assertQuerysetEqual( f.qs, ['aaron', 'alex', 'carl', 'jacob'], lambda o: o.username) f = F({'o': 'status'}, queryset=self.qs) self.assertQuerysetEqual( f.qs, ['carl', 'alex', 'jacob', 'aaron'], lambda o: o.username) @unittest.skip('todo') def test_ordering_uses_filter_name(self): class F(FilterSet): account = CharFilter(name='username') class Meta: model = User fields = ['account', 'status'] order_by = True f = F({'o': 'username'}, queryset=self.qs) self.assertQuerysetEqual( f.qs, ['aaron', 'alex', 'carl', 'jacob'], lambda o: o.username) def test_ordering_with_overridden_field_name(self): """ Set the `order_by_field` on the queryset and ensure that the field name is respected. """ class F(FilterSet): order_by_field = 'order' class Meta: model = User fields = ['username', 'status'] order_by = ['status'] f = F({'order': 'status'}, queryset=self.qs) self.assertQuerysetEqual( f.qs, ['carl', 'alex', 'jacob', 'aaron'], lambda o: o.username) def test_ordering_descending_set(self): class F(FilterSet): class Meta: model = User fields = ['username', 'status'] order_by = ['username', '-username'] f = F({'o': '-username'}, queryset=self.qs) self.assertQuerysetEqual( f.qs, ['jacob', 'carl', 'alex', 'aaron'], lambda o: o.username) def test_ordering_descending_unset(self): """ Test ordering descending works when order_by=True. """ class F(FilterSet): class Meta: model = User fields = ['username', 'status'] order_by = True f = F({'o': '-username'}, queryset=self.qs) self.assertQuerysetEqual( f.qs, ['jacob', 'carl', 'alex', 'aaron'], lambda o: o.username) def test_custom_ordering(self): class F(FilterSet): debug = True class Meta: model = User fields = ['username', 'status'] order_by = ['username', 'status'] def get_order_by(self, order_choice): if order_choice == 'status': return ['status', 'username'] return super(F, self).get_order_by(order_choice) f = F({'o': 'username'}, queryset=self.qs) self.assertQuerysetEqual( f.qs, ['aaron', 'alex', 'carl', 'jacob'], lambda o: o.username) f = F({'o': 'status'}, queryset=self.qs) self.assertQuerysetEqual( f.qs, ['carl', 'alex', 'aaron', 'jacob'], lambda o: o.username) class FilterSetTogetherTests(TestCase): def setUp(self): self.alex = User.objects.create(username='alex', status=1) self.jacob = User.objects.create(username='jacob', status=2) self.qs = User.objects.all().order_by('id') def test_fields_set(self): class F(FilterSet): class Meta: model = User fields = ['username', 'status', 'is_active', 'first_name'] together = [ ('username', 'status'), ('first_name', 'is_active'), ] f = F({}, queryset=self.qs) self.assertEqual(f.qs.count(), 2) f = F({'username': 'alex'}, queryset=self.qs) self.assertEqual(f.qs.count(), 0) f = F({'username': 'alex', 'status': 1}, queryset=self.qs) self.assertEqual(f.qs.count(), 1) self.assertQuerysetEqual(f.qs, [self.alex.pk], lambda o: o.pk) def test_single_fields_set(self): class F(FilterSet): class Meta: model = User fields = ['username', 'status'] together = ['username', 'status'] f = F({}, queryset=self.qs) self.assertEqual(f.qs.count(), 2) f = F({'username': 'alex'}, queryset=self.qs) self.assertEqual(f.qs.count(), 0) f = F({'username': 'alex', 'status': 1}, queryset=self.qs) self.assertEqual(f.qs.count(), 1) self.assertQuerysetEqual(f.qs, [self.alex.pk], lambda o: o.pk) django-filter-0.11.0/tests/test_filterset.pyc0000644000076500000240000012742112525716216022040 0ustar carltonstaff00000000000000ó Ä_SUc@@s©ddlmZmZddlZddlZejd1krLddlZnddlmZddlm Z ddl m Z ddl m Z dd l mZdd l mZdd lmZdd lmZdd lmZddlmZddlmZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl mZddl m Z ddl m!Z!ddl m"Z"ddl m#Z#ddl m$Z$d „Z%d!e fd"„ƒYZ&d#e fd$„ƒYZ'd%e fd&„ƒYZ(d'e fd(„ƒYZ)d)e fd*„ƒYZ*d+e fd,„ƒYZ+d-e fd.„ƒYZ,d/e fd0„ƒYZ-dS(2i(tabsolute_importtunicode_literalsNii(tunittest(tmodels(tTestCase(t FilterSet(tFILTER_FOR_DBFIELD_DEFAULTS(tget_model_field(t CharFilter(t NumberFilter(t ChoiceFilter(tModelChoiceFilter(tModelMultipleChoiceFilteri(tUser(t AdminUser(tBook(tProfile(tComment(t Restaurant(tNetworkSetting(tSubnetMaskField(tAccount(t BankAccount(tNode(t DirectedNode(tWorker(t HiredWorker(tBusinesscC@s.t|ƒt|ƒko-t|ƒt|ƒkS(uE TestCase.assertItemsEqual() is not available in Python 2.6. (tlentsorted(tL1tL2((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pytcheckItemsEqual(stHelperMethodsTestscB@sbeZejdƒd„ƒZd„Zd„Zejdƒd„ƒZejdƒd„ƒZRS(utodocC@sdS(N((tself((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_get_declared_filters0scC@s ttdƒ}|j|ƒdS(Nu unknown__name(RR t assertIsNone(R"tresult((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_get_model_field_none4scC@s/ttdƒ}|j|tjjdƒƒdS(Nuhiredworker__workeruworker(RRt assertEqualRt_metat get_field(R"R%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_get_model_field8scC@sdS(N((R"((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_filters_for_model<scC@sdS(N((R"((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_filterset_factory@s( t__name__t __module__RtskipR#R&R*R+R,(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR!.s   tDbFieldDefaultFiltersTestscB@seZd„Zd„ZRS(cC@s¿tjtjtjtjtjtjtjtjtj tj tj tj tj tjtjtjtjtjtjtjtjtjg}d}x(|D] }|j|t||jƒq—WdS(Nu6%s expected to be found in FILTER_FOR_DBFIELD_DEFAULTS(Rt BooleanFieldt CharFieldtCommaSeparatedIntegerFieldt DateFieldt DateTimeFieldt DecimalFieldt EmailFieldt FilePathFieldt FloatFieldt IntegerFieldtIPAddressFieldtNullBooleanFieldtPositiveIntegerFieldtPositiveSmallIntegerFieldt SlugFieldtSmallIntegerFieldt TextFieldt TimeFieldtURLFieldt ForeignKeyt OneToOneFieldtManyToManyFieldtassertInRR-(R"tto_checktmsgtm((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt#test_expected_db_fields_get_filtersGs2  cC@sYtjtjtjtjtjg}d}x(|D] }|j|t||jƒq1WdS(Nu:%s expected to not be found in FILTER_FOR_DBFIELD_DEFAULTS( RtFieldtBigIntegerFieldtGenericIPAddressFieldt FileFieldt ImageFieldt assertNotInRR-(R"RHRIRJ((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt*test_expected_db_fields_do_not_get_filterses  (R-R.RKRR(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR0Es tFilterSetFilterForFieldTestscB@sheZd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Z e j dƒd „ƒZ RS( cC@sKtjjdƒ}tj|dƒ}|j|tƒ|j|jdƒdS(Nuusername( R R(R)Rtfilter_for_fieldtassertIsInstanceRR'tname(R"tfR%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_filter_found_for_fielduscC@sKtjjdƒ}tj|dƒ}|j|tƒ|j|jdƒdS(Nuid( R R(R)RRTRUR R'RV(R"RWR%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_filter_found_for_autofield{scC@stjjdƒ}tj|dƒ}|j|tƒ|j|jdƒ|j d|j kƒ|j |j dƒ|j|j dj t ƒdS(Nufavorite_booksuqueryset(R R(R)RRTRUR R'RVt assertTruetextratassertIsNotNonetmodelR(R"RWR%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_field_with_extrasscC@sutjjdƒ}tj|dƒ}|j|tƒ|j|jdƒ|j d|j kƒ|j |j dƒdS(Nustatusuchoices( R R(R)RRTRUR R'RVRZR[R\(R"RWR%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_field_with_choicesŠs cC@s8tjjdƒ}tj|dƒ}|j|tƒdS(Nu first_name(R R(R)RRTRUR(R"RWR%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_field_that_is_subclassed’scC@stjjdƒ}tj|dƒ}|j|tƒ|j|jdƒ|j d|j kƒ|j |j dƒ|j|j dj tƒdS(Nu adjacentsuqueryset( RR(R)RRTRUR R'RVRZR[R\R](R"RWR%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt"test_symmetrical_selfref_m2m_field—scC@stjjdƒ}tj|dƒ}|j|tƒ|j|jdƒ|j d|j kƒ|j |j dƒ|j|j dj tƒdS(Nuoutbound_nodesuqueryset( RR(R)RRTRUR R'RVRZR[R\R](R"RWR%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt&test_non_symmetrical_selfref_m2m_field scC@stjjdƒ}tj|dƒ}|j|tƒ|j|jdƒ|j d|j kƒ|j |j dƒ|j|j dj t ƒdS(Nu employeesuqueryset(RR(R)RRTRUR R'RVRZR[R\R]R(R"RWR%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt!test_m2m_field_with_through_model©sutodocC@sdS(N((R"((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_filter_overrides²s( R-R.RXRYR^R_R`RaRbRcRR/Rd(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRSss     t#FilterSetFilterForReverseFieldTestscB@s5eZd„Zd„Zd„Zd„Zd„ZRS(cC@s“tjjdƒd}tj|dƒ}|j|tƒ|j|jdƒ|j d|j kƒ|j |j dƒ|j|j dj t ƒdS(Nuprofileiuqueryset(RR(tget_field_by_nameRtfilter_for_reverse_fieldRUR R'RVRZR[R\R]R(R"RWR%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_reverse_o2o_relationship¹scC@s“tjjdƒd}tj|dƒ}|j|tƒ|j|jdƒ|j d|j kƒ|j |j dƒ|j|j dj t ƒdS(Nucommentsiuqueryset(R R(RfRRgRUR R'RVRZR[R\R]R(R"RWR%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_reverse_fk_relationshipÂscC@s“tjjdƒd}tj|dƒ}|j|tƒ|j|jdƒ|j d|j kƒ|j |j dƒ|j|j dj t ƒdS(Nuloversiuqueryset(RR(RfRRgRUR R'RVRZR[R\R]R (R"RWR%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_reverse_m2m_relationshipËscC@s“tjjdƒd}tj|dƒ}|j|tƒ|j|jdƒ|j d|j kƒ|j |j dƒ|j|j dj tƒdS(Nu inbound_nodesiuqueryset( RR(RfRRgRUR R'RVRZR[R\R](R"RWR%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt.test_reverse_non_symmetrical_selfref_m2m_fieldÔscC@s“tjjdƒd}tj|dƒ}|j|tƒ|j|jdƒ|j d|j kƒ|j |j dƒ|j|j dj t ƒdS(Nu employersiuqueryset(RR(RfRRgRUR R'RVRZR[R\R]R(R"RWR%((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt)test_reverse_m2m_field_with_through_modelÝs(R-R.RhRiRjRkRl(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRe·s  tFilterSetClassCreationTestscB@s³eZd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z d „Z d „Z d „Z d „Zd „Zd„Zd„Zd„Zejd„ƒZRS(cC@sLdtfd„ƒY}|jt|jƒdƒ|jt|jƒdƒdS(NtFcB@seZRS((R-R.(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnêsi(RR'Rtdeclared_filterst base_filters(R"Rn((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_no_filterséscC@s„dtfd„ƒY}|jt|jƒdƒ|jt|jƒdgƒ|jt|jƒdƒ|jt|jƒdgƒdS(NRncB@seZeƒZRS((R-R.Rtusername(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnñsiuusername(RR'RRotassertListEqualtlistRp(R"Rn((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_declaring_filterðs cC@sndtfd„ƒY}|jt|jƒdƒ|jt|jƒdƒ|jt|jƒdddgƒdS(NRncB@seZddd„ƒYZRS(tMetacB@seZeZRS((R-R.RR](((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvûs((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnúsiiutitleupriceuaverage_rating(RR'RRoRpRsRt(R"Rn((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_model_derivedùs cC@sqdtfd„ƒY}|jt|jƒdƒ|jt|jƒdƒ|jt|jƒddddgƒdS( NRncB@s$eZeƒZddd„ƒYZRS(RvcB@seZeZRS((R-R.RR](((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvs((R-R.RRrRv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRns iiutitleupriceuaverage_ratinguusername(RR'RRoRpRsRt(R"Rn((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_declared_and_model_deriveds cC@skdtfd„ƒY}|jt|jƒdƒ|jt|jƒdƒ|jt|jƒddgƒdS(NRncB@s$eZeƒZddd„ƒYZRS(RvcB@seZeZdZRS(uusernameuprice(uusernameuprice(R-R.RR]tfields(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvs((R-R.RRrRv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRns iiuusernameuprice(RR'RRoRpRsRt(R"Rn((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt0test_meta_fields_with_declared_and_model_derivedscC@szdtfd„ƒY}|jt|jƒdƒ|jt|jƒdƒdddg}|jtt|jƒ|ƒƒdS(NRncB@seZddd„ƒYZRS(RvcB@s$eZeZidddgd6ZRS(uexactugteulteuprice(R-R.RR]Ry(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvs((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnsiiupriceu price__gteu price__lte(RR'RRoRpRZR Rt(R"Rnt expected_list((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt#test_meta_fields_dictionary_deriveds cC@sndtfd„ƒY}|jt|jƒdƒ|jt|jƒdƒ|jt|jƒdddgƒdS(NRncB@s$eZeƒZddd„ƒYZRS(RvcB@seZeZdZRS(uiduusernameuprice(uiduusernameuprice(R-R.RR]Ry(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRv,s((R-R.RRrRv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRn)s iiuiduusernameuprice(RR'RRoRpRsRt(R"Rn((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt%test_meta_fields_containing_autofield(scC@swdtfd„ƒY}|jt|jƒdƒ|jt|jƒdƒddg}|jtt|jƒ|ƒƒdS(NRncB@s$eZeƒZddd„ƒYZRS(RvcB@s(eZeZidgd6dgd6ZRS(uexactuiduusername(R-R.RR]Ry(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRv8s ((R-R.RRrRv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRn5s iiuiduusername(RR'RRoRpRZR Rt(R"RnR{((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt%test_meta_fields_dictionary_autofield4s   cC@s0|jtƒdtfd„ƒY}WdQXdS(NRncB@s$eZeƒZddd„ƒYZRS(RvcB@seZeZdZRS(uusernameupriceuother(uusernameupriceuother(R-R.RR]Ry(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvIs((R-R.RRrRv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnFs (t assertRaisest TypeErrorR(R"Rn((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt#test_meta_fields_containing_unknownDscC@s0|jtƒdtfd„ƒY}WdQXdS(NRncB@seZddd„ƒYZRS(RvcB@s2eZeZidgd6dgd6dgd6ZRS(uexactuidutitleuother(R-R.RR]Ry(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvQs  ((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnOs(RR€R(R"Rn((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt.test_meta_fields_dictionary_containing_unknownMscC@sndtfd„ƒY}|jt|jƒdƒ|jt|jƒdƒ|jt|jƒdddgƒdS(NRncB@s$eZeƒZddd„ƒYZRS(RvcB@seZeZdZRS(uusernameuprice(uusernameuprice(R-R.RR]texclude(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRv\s((R-R.RRrRv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnYs iiutitleuaverage_ratinguusername(RR'RRoRpRsRt(R"Rn((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt0test_meta_exlude_with_declared_and_declared_winsXs cC@skdtfd„ƒY}|jt|jƒdƒ|jt|jƒdƒ|jt|jƒddgƒdS(NRncB@s$eZeƒZddd„ƒYZRS(RvcB@seZeZdZdZRS(uusernameutitleuprice(uusernameutitleuprice(utitle(R-R.RR]RyRƒ(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvis((R-R.RRrRv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnfs iiuusernameuprice(RR'RRoRpRsRt(R"Rn((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt,test_meta_fields_and_exlude_and_exclude_winses cC@s dtfd„ƒY}d|fd„ƒY}|jt|jƒt|jƒƒdtfd„ƒY}d|fd„ƒY}|jt|jƒt|jƒƒdS(NRncB@seZddd„ƒYZRS(RvcB@seZeZRS((R-R.RR](((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvus((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRntstGcB@seZRS((R-R.(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR†xscB@s!eZeZddd„ƒYZRS(RvcB@seZeZRS((R-R.RR](((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvs((R-R.RtotherRv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRn|scB@seZRS((R-R.(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR†‚s(RR'tsetRp(R"RnR†((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt test_filterset_class_inheritancess "cC@szdtfd„ƒY}|jt|jƒtddgƒƒdtfd„ƒY}|jt|jƒtddgƒƒdS(NRncB@seZddd„ƒYZRS(RvcB@seZeZRS((R-R.RR](((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvˆs((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRn‡sunameu serves_pizzacB@seZddd„ƒYZRS(RvcB@seZeZddgZRS(unameu serves_pizza(R-R.RR]Ry(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvŽs((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRns(RR'RˆRp(R"Rn((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_abstract_model_inheritance†s%cC@s<dtfd„ƒY}|jt|jjƒƒdgƒdS(NRncB@seZddd„ƒYZRS(RvcB@seZeZRS((R-R.RR](((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRv–s((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRn•suip(RR'RtRptkeys(R"Rn((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_custom_field_ignored”scC@s?dtfd„ƒY}|jt|jjƒƒddgƒdS(NRncB@s/eZiied6e6Zddd„ƒYZRS(u filter_classRvcB@seZeZRS((R-R.RR](((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRv s((R-R.RRtfilter_overridesRv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnœsuipumask(RR'RtRpR‹(R"Rn((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt+test_custom_field_gets_filter_from_override›scC@sRdtfd„ƒY}dtfd„ƒY}|jt|jƒt|jƒƒdS(NRncB@seZddd„ƒYZRS(RvcB@seZeZRS((R-R.R R](((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRv§s((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRn¦stProxyFcB@seZddd„ƒYZRS(RvcB@seZeZRS((R-R.RR](((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRv«s((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRªs(RR'RtRp(R"RnR((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_filterset_for_proxy_model¥scC@sYdtfd„ƒY}dtfd„ƒY}|jt|jƒdgt|jƒƒdS(NRncB@seZddd„ƒYZRS(RvcB@seZeZRS((R-R.RR](((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRv³s((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRn²stFtiFcB@seZddd„ƒYZRS(RvcB@seZeZRS((R-R.RR](((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRv·s((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR‘¶su amount_saved(RR'RtRp(R"RnR‘((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_filterset_for_mti_model°s (R-R.RqRuRwRxRzR|R}R~RR‚R„R…R‰RŠRŒRŽRRtexpectedFailureR’(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRmçs$       tFilterSetInstantiationTestscB@s#eZd„Zd„Zd„ZRS(cC@sŸdtfd„ƒY}|ƒ}|j|jƒ|j|jƒ|jt|jƒt|jƒƒx7|jj ƒD]&\}}|j|j t d|ƒqqWdS(NRncB@seZddd„ƒYZRS(RvcB@seZeZdgZRS(uusername(R-R.R R]Ry(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvÄs((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnÃsu$%s does not have model set correctly( Rt assertFalsetis_boundR\tquerysetR'RtfiltersRptitemsR]R (R"RnRWRVtfilter_((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_creating_instanceÂs "cC@s=dtfd„ƒY}|idd6ƒ}|j|jƒdS(NRncB@seZddd„ƒYZRS(RvcB@seZeZdgZRS(uusername(R-R.R R]Ry(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvÔs((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnÓsuusername(RRZR–(R"RnRW((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_creating_bound_instanceÒscC@sHdtfd„ƒY}tjƒ}|d|ƒ}|j|j|ƒdS(NRncB@seZddd„ƒYZRS(RvcB@seZeZdgZRS(uusername(R-R.R R]Ry(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvÝs((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnÜsR—(RtmocktMockR'R—(R"RnRJRW((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_creating_with_querysetÛs (R-R.R›RœRŸ(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR”Às  tFilterSetOrderingTestscB@szeZd„Zd„Zd„Zd„Zd„Zd„Zej dƒd„ƒZ d„Z d „Z d „Z d „ZRS( cC@s—tjjddddƒ|_tjjddddƒ|_tjjddddƒ|_tjjdddd ƒ|_tjjƒjd ƒ|_ dS( NRrualextstatusiujacobiuaaronucarliuid( R tobjectstcreatetalextjacobtaarontcarltalltorder_bytqs(R"((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pytsetUpès cC@sQdtfd„ƒY}|d|jƒ}|j|jddddgd„ƒdS( NRncB@seZddd„ƒYZRS(RvcB@s#eZeZddgZdgZRS(uusernameustatus(R-R.R R]RyR©(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvòs ((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnñsR—ucarlualexujacobuaaroncS@s|jS(N(Rr(to((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pytùs(RRªtassertQuerysetEqual(R"RnRW((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_ordering_when_unboundðscC@sœdtfd„ƒY}|idd6d|jƒ}|j|jdddd gd „ƒ|id d6d|jƒ}|j|jddd dgd „ƒdS( NRncB@seZddd„ƒYZRS(RvcB@s&eZeZddgZddgZRS(uusernameustatus(R-R.R R]RyR©(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvýs ((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnüsuusernameuoR—uaaronualexucarlujacobcS@s|jS(N(Rr(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­sustatuscS@s|jS(N(Rr(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­s(RRªR®(R"RnRW((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt test_orderingûscC@sOdtfd„ƒY}|idd6d|jƒ}|j|jgd„ƒdS(NRncB@seZddd„ƒYZRS(RvcB@s#eZeZddgZdgZRS(uusernameustatus(R-R.R R]RyR©(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRv s ((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRn suusernameuoR—cS@s|jS(N(Rr(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­s(RRªR®(R"RnRW((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_ordering_on_unknown_value scC@s[dtfd„ƒY}|idd6d|jƒ}|j|jdddd gd „ƒdS( NRncB@s!eZeZddd„ƒYZRS(RvcB@s#eZeZddgZdgZRS(uusernameustatus(R-R.R R]RyR©(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvs ((R-R.tFalsetstrictRv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnsuusernameuoR—ualexujacobuaaronucarlcS@s|jS(N(Rr(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­ s(RRªR®(R"RnRW((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pytItest_ordering_on_unknown_value_results_in_default_ordering_without_strictscC@sœdtfd„ƒY}|idd6d|jƒ}|j|jdddd gd „ƒ|id d6d|jƒ}|j|jddd dgd „ƒdS( NRncB@seZddd„ƒYZRS(RvcB@s eZeZddgZeZRS(uusernameustatus(R-R.R R]RytTrueR©(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRv$s ((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRn#suusernameuoR—uaaronualexucarlujacobcS@s|jS(N(Rr(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­+sustatuscS@s|jS(N(Rr(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­/s(RRªR®(R"RnRW((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt test_ordering_on_different_field"sutodocC@s[dtfd„ƒY}|idd6d|jƒ}|j|jdddd gd „ƒdS( NRncB@s*eZeddƒZddd„ƒYZRS(RVuusernameRvcB@s eZeZddgZeZRS(uaccountustatus(R-R.R R]RyRµR©(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRv6s ((R-R.RtaccountRv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRn3suusernameuoR—uaaronualexucarlujacobcS@s|jS(N(Rr(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­=s(RRªR®(R"RnRW((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_ordering_uses_filter_name1scC@s[dtfd„ƒY}|idd6d|jƒ}|j|jdddd gd „ƒd S( uo Set the `order_by_field` on the queryset and ensure that the field name is respected. RncB@s!eZdZddd„ƒYZRS(uorderRvcB@s#eZeZddgZdgZRS(uusernameustatus(R-R.R R]RyR©(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvGs ((R-R.torder_by_fieldRv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnDsustatusuorderR—ucarlualexujacobuaaroncS@s|jS(N(Rr(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­NsN(RRªR®(R"RnRW((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyt(test_ordering_with_overridden_field_name?scC@s[dtfd„ƒY}|idd6d|jƒ}|j|jdddd gd „ƒdS( NRncB@seZddd„ƒYZRS(RvcB@s&eZeZddgZddgZRS(uusernameustatusu -username(R-R.R R]RyR©(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvRs ((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnQsu -usernameuoR—ujacobucarlualexuaaroncS@s|jS(N(Rr(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­Ys(RRªR®(R"RnRW((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_ordering_descending_setPscC@s[dtfd„ƒY}|idd6d|jƒ}|j|jdddd gd „ƒd S( u4 Test ordering descending works when order_by=True. RncB@seZddd„ƒYZRS(RvcB@s eZeZddgZeZRS(uusernameustatus(R-R.R R]RyRµR©(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRv^s ((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRn]su -usernameuoR—ujacobucarlualexuaaroncS@s|jS(N(Rr(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­esN(RRªR®(R"RnRW((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_ordering_descending_unset[sc@s¢dtf‡fd†ƒY‰ˆidd6d|jƒ}|j|jdddd gd „ƒˆid d6d|jƒ}|j|jdddd gd „ƒdS( NRnc@s0eZeZddd„ƒYZ‡fd†ZRS(RvcB@s&eZeZddgZddgZRS(uusernameustatus(R-R.R R]RyR©(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvks c@s,|dkrddgStˆ|ƒj|ƒS(Nustatusuusername(tsupert get_order_by(R"t order_choice(Rn(sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR¾ps  ((R-R.RµtdebugRvR¾((Rn(sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRnisuusernameuoR—uaaronualexucarlujacobcS@s|jS(N(Rr(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­wsustatuscS@s|jS(N(Rr(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­{s(RRªR®(R"RW((RnsK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_custom_orderinggs (R-R.R«R¯R°R±R´R¶RR/R¸RºR»R¼RÁ(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR æs     tFilterSetTogetherTestscB@s#eZd„Zd„Zd„ZRS(cC@s[tjjddddƒ|_tjjddddƒ|_tjjƒjdƒ|_dS(NRrualexR¡iujacobiuid(R R¢R£R¤R¥R¨R©Rª(R"((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR«scC@sÛdtfd„ƒY}|id|jƒ}|j|jjƒdƒ|idd6d|jƒ}|j|jjƒdƒ|idd6dd 6d|jƒ}|j|jjƒdƒ|j|j|jjgd „ƒdS( NRncB@seZddd„ƒYZRS(RvcB@s,eZeZddddgZddgZRS(uusernameustatusu is_activeu first_name(uusernameustatus(u first_nameu is_active(R-R.R R]Ryttogether(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvˆs((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRn‡sR—iualexuusernameiiustatuscS@s|jS(N(tpk(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­–s(RRªR'tcountR®R¤RÄ(R"RnRW((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_fields_set†s #cC@sÛdtfd„ƒY}|id|jƒ}|j|jjƒdƒ|idd6d|jƒ}|j|jjƒdƒ|idd6dd 6d|jƒ}|j|jjƒdƒ|j|j|jjgd „ƒdS( NRncB@seZddd„ƒYZRS(RvcB@s&eZeZddgZddgZRS(uusernameustatus(R-R.R R]RyRÃ(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRvšs ((R-R.Rv(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRn™sR—iualexuusernameiiustatuscS@s|jS(N(RÄ(R¬((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyR­¥s(RRªR'RÅR®R¤RÄ(R"RnRW((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyttest_single_fields_set˜s#(R-R.R«RÆRÇ(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pyRÂs  (ii(.t __future__RRRtsyst version_infoRt django.utilst django.dbRt django.testRtdjango_filters.filtersetRRRtdjango_filters.filtersRR R R R R RRRRRRRRRRRRRRR R!R0RSReRmR”R RÂ(((sK/Users/carlton/Documents/Django-Stack/django-filter/tests/test_filterset.pytsN   .D0Ù&™django-filter-0.11.0/tests/test_forms.py0000644000076500000240000002043412411012542020777 0ustar carltonstaff00000000000000from __future__ import absolute_import from __future__ import unicode_literals from django import forms from django.test import TestCase from django_filters.filterset import FilterSet from django_filters.filters import CharFilter from django_filters.filters import ChoiceFilter from .models import User from .models import Book from .models import STATUS_CHOICES class FilterSetFormTests(TestCase): def test_form_from_empty_filterset(self): class F(FilterSet): pass f = F(queryset=Book.objects.all()).form self.assertIsInstance(f, forms.Form) def test_form(self): class F(FilterSet): class Meta: model = Book fields = ('title',) f = F().form self.assertIsInstance(f, forms.Form) self.assertEqual(list(f.fields), ['title']) def test_custom_form(self): class MyForm(forms.Form): pass class F(FilterSet): class Meta: model = Book form = MyForm f = F().form self.assertIsInstance(f, MyForm) def test_form_prefix(self): class F(FilterSet): class Meta: model = Book fields = ('title',) f = F().form self.assertIsNone(f.prefix) f = F(prefix='prefix').form self.assertEqual(f.prefix, 'prefix') def test_form_fields(self): class F(FilterSet): class Meta: model = User fields = ['status'] f = F().form self.assertEqual(len(f.fields), 1) self.assertIn('status', f.fields) self.assertEqual(sorted(f.fields['status'].choices), sorted(STATUS_CHOICES)) def test_form_fields_exclusion(self): class F(FilterSet): title = CharFilter(exclude=True) class Meta: model = Book fields = ('title',) f = F().form self.assertEqual(f.fields['title'].help_text, "This is an exclusion filter") def test_form_fields_using_widget(self): class F(FilterSet): status = ChoiceFilter(widget=forms.RadioSelect, choices=STATUS_CHOICES) class Meta: model = User fields = ['status', 'username'] f = F().form self.assertEqual(len(f.fields), 2) self.assertIn('status', f.fields) self.assertIn('username', f.fields) self.assertEqual(sorted(f.fields['status'].choices), sorted(STATUS_CHOICES)) self.assertIsInstance(f.fields['status'].widget, forms.RadioSelect) def test_form_field_with_custom_label(self): class F(FilterSet): title = CharFilter(label="Book title") class Meta: model = Book fields = ('title',) f = F().form 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): book_title = CharFilter(name='title') class Meta: model = Book fields = ('book_title',) f = F().form 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): f1 = CharFilter(name='title', label="Book title") class Meta: model = Book fields = ('f1',) f = F().form self.assertEqual(f.fields['f1'].label, "Book title") self.assertEqual(f['f1'].label, 'Book title') def test_filter_with_initial(self): class F(FilterSet): status = ChoiceFilter(choices=STATUS_CHOICES, initial=1) class Meta: model = User fields = ['status'] 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): class Meta: model = User fields = ['username', 'status'] order_by = ['status'] f = F().form self.assertEqual(len(f.fields), 3) self.assertIn('o', f.fields) self.assertEqual(f.fields['o'].choices, [('status', 'Status')]) def test_ordering_uses_all_fields(self): class F(FilterSet): class Meta: model = User fields = ['username', 'status'] order_by = True f = F().form self.assertEqual(f.fields['o'].choices, [('username', 'Username'), ('-username', 'Username (descending)'), ('status', 'Status'), ('-status', 'Status (descending)')]) def test_ordering_uses_filter_label(self): class F(FilterSet): username = CharFilter(label='Account') class Meta: model = User fields = ['username', 'status'] order_by = True f = F().form self.assertEqual(f.fields['o'].choices, [('username', 'Account'), ('-username', 'Account (descending)'), ('status', 'Status'), ('-status', 'Status (descending)')]) def test_ordering_uses_implicit_filter_name(self): class F(FilterSet): account = CharFilter(name='username') class Meta: model = User fields = ['account', 'status'] order_by = True f = F().form self.assertEqual(f.fields['o'].choices, [('username', 'Account'), ('-username', 'Account (descending)'), ('status', 'Status'), ('-status', 'Status (descending)')]) def test_ordering_with_overridden_field_name(self): """ Set the `order_by_field` on the queryset and ensure that the field name is respected. """ class F(FilterSet): order_by_field = 'order' class Meta: model = User fields = ['username', 'status'] order_by = ['status'] f = F().form self.assertNotIn('o', f.fields) self.assertIn('order', f.fields) self.assertEqual(f.fields['order'].choices, [('status', 'Status')]) def test_ordering_with_overridden_field_name_and_descending(self): """ Set the `order_by_field` on the queryset and ensure that the field name is respected. """ class F(FilterSet): order_by_field = 'order' class Meta: model = User fields = ['username', 'status'] order_by = ['status', '-status'] f = F().form self.assertNotIn('o', f.fields) self.assertIn('order', f.fields) self.assertEqual(f.fields['order'].choices, [('status', 'Status'), ('-status', 'Status (descending)')]) def test_ordering_with_overridden_field_name_and_using_all_fields(self): class F(FilterSet): order_by_field = 'order' class Meta: model = User fields = ['username', 'status'] order_by = True f = F().form self.assertIn('order', f.fields) self.assertEqual(f.fields['order'].choices, [('username', 'Username'), ('-username', 'Username (descending)'), ('status', 'Status'), ('-status', 'Status (descending)')]) def test_ordering_with_custom_display_names(self): class F(FilterSet): class Meta: model = User fields = ['username', 'status'] order_by = [('status', 'Current status')] f = F().form self.assertEqual( f.fields['o'].choices, [('status', 'Current status')]) django-filter-0.11.0/tests/test_forms.pyc0000644000076500000240000004534712411012721021153 0ustar carltonstaff00000000000000ó b$Tc@@sºddlmZddlmZddlmZddlmZddlmZddl m Z ddl m Z dd l m Z dd l mZdd l mZd efd „ƒYZdS(i(tabsolute_import(tunicode_literals(tforms(tTestCase(t FilterSet(t CharFilter(t ChoiceFilteri(tUser(tBook(tSTATUS_CHOICEStFilterSetFormTestscB@sÅeZd„Zd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z d „Z d „Z d „Z d „Zd „Zd„Zd„Zd„Zd„Zd„Zd„Zd„ZRS(cC@sHdtfd„ƒY}|dtjjƒƒj}|j|tjƒdS(NtFcB@seZRS((t__name__t __module__(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR stqueryset(RRtobjectstalltformtassertIsInstanceRtForm(tselfR tf((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyttest_form_from_empty_filtersetscC@sUdtfd„ƒY}|ƒj}|j|tjƒ|jt|jƒdgƒdS(NR cB@seZddd„ƒYZRS(tMetacB@seZeZdZRS(utitle(utitle(R R Rtmodeltfields(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyRs((R R R(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR sutitle(RRRRRt assertEqualtlistR(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyt test_forms c@sUdtjfd„ƒY‰dtf‡fd†ƒY}|ƒj}|j|ˆƒdS(NtMyFormcB@seZRS((R R (((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR$sR c@s!eZdd‡fd†ƒYZRS(Rc@seZeZˆZRS((R R RRR((R(sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR(s((R R R((R(sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR 's(RRRRR(RR R((RsG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyttest_custom_form#s cC@s[dtfd„ƒY}|ƒj}|j|jƒ|ddƒj}|j|jdƒdS(NR cB@seZddd„ƒYZRS(RcB@seZeZdZRS(utitle(utitle(R R RRR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR1s((R R R(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR 0stprefixuprefix(RRt assertIsNoneRR(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyttest_form_prefix/s  cC@sxdtfd„ƒY}|ƒj}|jt|jƒdƒ|jd|jƒ|jt|jdjƒttƒƒdS(NR cB@seZddd„ƒYZRS(RcB@seZeZdgZRS(ustatus(R R RRR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR=s((R R R(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR <siustatus( RRRtlenRtassertIntsortedtchoicesR (RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyttest_form_fields;s  cC@s@dtfd„ƒY}|ƒj}|j|jdjdƒdS(NR cB@s*eZedeƒZddd„ƒYZRS(texcludeRcB@seZeZdZRS(utitle(utitle(R R RRR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyRKs((R R RtTruettitleR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR HsutitleuThis is an exclusion filter(RRRRt help_text(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyttest_form_fields_exclusionGs cC@s¨dtfd„ƒY}|ƒj}|jt|jƒdƒ|jd|jƒ|jd|jƒ|jt|jdjƒttƒƒ|j |jdj t j ƒdS(NR cB@s3eZedejdeƒZddd„ƒYZRS(twidgetR%RcB@seZeZddgZRS(ustatusuusername(R R RRR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyRWs((R R RRt RadioSelectR tstatusR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR Ss iustatusuusername( RRRR"RR#R$R%R RR,RR-(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyttest_form_fields_using_widgetRs  cC@sWdtfd„ƒY}|ƒj}|j|jdjdƒ|j|djdƒdS(NR cB@s*eZeddƒZddd„ƒYZRS(tlabelu Book titleRcB@seZeZdZRS(utitle(utitle(R R RRR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyRgs((R R RR)R(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR dsutitleu Book title(RRRRR0(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyt!test_form_field_with_custom_labelcs cC@sWdtfd„ƒY}|ƒj}|j|jdjdƒ|j|djdƒdS(NR cB@s*eZeddƒZddd„ƒYZRS(tnameutitleRcB@seZeZdZRS(u book_title(u book_title(R R RRR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyRss((R R Rt book_titleR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR psu book_titleu Book title(RRRRR0tNone(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyt test_form_field_with_manual_nameos cC@sWdtfd„ƒY}|ƒj}|j|jdjdƒ|j|djdƒdS(NR cB@s0eZeddddƒZddd„ƒYZRS(R2utitleR0u Book titleRcB@seZeZdZRS(uf1(uf1(R R RRR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyRs((R R Rtf1R(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR |suf1u Book title(RRRRR0(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyt*test_form_field_with_manual_name_and_label{s cC@s@dtfd„ƒY}|ƒj}|j|jdjdƒdS(NR cB@s0eZededdƒZddd„ƒYZRS(R%tinitialiRcB@seZeZdgZRS(ustatus(R R RRR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR‹s((R R RR R.R(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR ˆsustatusi(RRRRR8(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyttest_filter_with_initial‡s cC@sIdtfd„ƒY}|ƒj}|j|jƒ|j|jiƒdS(NR cB@seZddd„ƒYZRS(RcB@seZeZdZRS(utitle(utitle(R R RRR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR”s((R R R(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR “s(RRt assertFalsetis_boundRtdata(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyttest_form_is_not_bound’s cC@sZdtfd„ƒY}|idd6ƒj}|j|jƒ|j|jidd6ƒdS(NR cB@seZddd„ƒYZRS(RcB@seZeZdZRS(utitle(utitle(R R RRR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyRžs((R R R(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR su Some bookutitle(RRt assertTrueR;RR<(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyttest_form_is_boundœscC@sodtfd„ƒY}|ƒj}|jt|jƒdƒ|jd|jƒ|j|jdjdgƒdS(NR cB@seZddd„ƒYZRS(RcB@s#eZeZddgZdgZRS(uusernameustatus(R R RRRtorder_by(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR¨s ((R R R(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR §siuoustatusuStatus(ustatusuStatus(RRRR"RR#R%(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyt test_ordering¦s  cC@sLdtfd„ƒY}|ƒj}|j|jdjd d ddgƒdS(NR cB@seZddd„ƒYZRS(RcB@s eZeZddgZeZRS(uusernameustatus(R R RRRR(R@(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR´s ((R R R(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR ³suouusernameuUsernameu -usernameuUsername (descending)ustatusuStatusu-statusuStatus (descending)(uusernameuUsername(u -usernameuUsername (descending)(ustatusuStatus(u-statusuStatus (descending)(RRRRR%(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyttest_ordering_uses_all_fields²s cC@sLdtfd„ƒY}|ƒj}|j|jdjd d ddgƒdS(NR cB@s*eZeddƒZddd„ƒYZRS(R0uAccountRcB@s eZeZddgZeZRS(uusernameustatus(R R RRRR(R@(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyRÁs ((R R RtusernameR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR ¾suouusernameuAccountu -usernameuAccount (descending)ustatusuStatusu-statusuStatus (descending)(uusernameuAccount(u -usernameuAccount (descending)(ustatusuStatus(u-statusuStatus (descending)(RRRRR%(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyttest_ordering_uses_filter_label½s cC@sLdtfd„ƒY}|ƒj}|j|jdjd d ddgƒdS(NR cB@s*eZeddƒZddd„ƒYZRS(R2uusernameRcB@s eZeZddgZeZRS(uaccountustatus(R R RRRR(R@(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyRÎs ((R R RtaccountR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR ËsuouusernameuAccountu -usernameuAccount (descending)ustatusuStatusu-statusuStatus (descending)(uusernameuAccount(u -usernameuAccount (descending)(ustatusuStatus(u-statusuStatus (descending)(RRRRR%(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyt'test_ordering_uses_implicit_filter_nameÊs cC@sidtfd„ƒY}|ƒj}|jd|jƒ|jd|jƒ|j|jdjdgƒdS( uo Set the `order_by_field` on the queryset and ensure that the field name is respected. R cB@s!eZdZddd„ƒYZRS(uorderRcB@s#eZeZddgZdgZRS(uusernameustatus(R R RRRR@(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyRßs ((R R torder_by_fieldR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR ÜsuouorderustatusuStatusN(ustatusuStatus(RRt assertNotInRR#RR%(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyt(test_ordering_with_overridden_field_name×s  cC@sldtfd„ƒY}|ƒj}|jd|jƒ|jd|jƒ|j|jdjd d gƒd S( uo Set the `order_by_field` on the queryset and ensure that the field name is respected. R cB@s!eZdZddd„ƒYZRS(uorderRcB@s&eZeZddgZddgZRS(uusernameustatusu-status(R R RRRR@(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyRñs ((R R RGR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR îsuouorderustatusuStatusu-statusuStatus (descending)N(ustatusuStatus(u-statusuStatus (descending)(RRRHRR#RR%(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyt7test_ordering_with_overridden_field_name_and_descendingés  cC@s_dtfd„ƒY}|ƒj}|jd|jƒ|j|jdjd d ddgƒdS(NR cB@s!eZdZddd„ƒYZRS(uorderRcB@s eZeZddgZeZRS(uusernameustatus(R R RRRR(R@(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyRÿs ((R R RGR(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR üsuorderuusernameuUsernameu -usernameuUsername (descending)ustatusuStatusu-statusuStatus (descending)(uusernameuUsername(u -usernameuUsername (descending)(ustatusuStatus(u-statusuStatus (descending)(RRR#RRR%(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyt=test_ordering_with_overridden_field_name_and_using_all_fieldsûs  cC@sCdtfd„ƒY}|ƒj}|j|jdjdgƒdS(NR cB@seZddd„ƒYZRS(RcB@s#eZeZddgZdgZRS(uusernameustatusuCurrent status(ustatusuCurrent status(R R RRRR@(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR s ((R R R(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR suoustatusuCurrent status(ustatusuCurrent status(RRRRR%(RR R((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyt'test_ordering_with_custom_display_names s (R R RRRR!R&R+R/R1R5R7R9R=R?RARBRDRFRIRJRKRL(((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pyR s*     N(t __future__RRtdjangoRt django.testRtdjango_filters.filtersetRtdjango_filters.filtersRRtmodelsRRR R (((sG/Users/carlton/Documents/Django-Stack/django-filter/tests/test_forms.pytsdjango-filter-0.11.0/tests/test_views.py0000644000076500000240000000540012524636137021023 0ustar carltonstaff00000000000000from __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 class GenericViewTestCase(TestCase): urls = 'tests.urls' def setUp(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 GenericClassBasedViewTests(GenericViewTestCase): base_url = '/books/' def test_view(self): response = self.client.get(self.base_url) for b in ['Ender's Game', 'Rainbow Six', 'Snowcrash']: self.assertContains(response, b) def test_view_filtering_on_title(self): response = self.client.get(self.base_url + '?title=Snowcrash') for b in ['Ender's Game', 'Rainbow Six']: 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/' def test_view(self): response = self.client.get(self.base_url) for b in ['Ender's Game', 'Rainbow Six', 'Snowcrash']: self.assertContains(response, b) def test_view_filtering_on_price(self): response = self.client.get(self.base_url + '?title=Snowcrash') for b in ['Ender's Game', 'Rainbow Six']: self.assertNotContains(response, b) self.assertContains(response, 'Snowcrash') django-filter-0.11.0/tests/test_views.pyc0000644000076500000240000001123012524640063021155 0ustar carltonstaff00000000000000ó _s *django-filter-0.11.0/tests/test_widgets.py0000644000076500000240000001110012410601557021316 0ustar carltonstaff00000000000000from __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 from django_filters.widgets import LookupTypeWidget class LookupTypeWidgetTests(TestCase): def test_widget_requires_field(self): 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', ''), """ """) self.assertHTMLEqual(w.render('price', None), """ """) self.assertHTMLEqual(w.render('price', ['2', 'a']), """ """) class LinkWidgetTests(TestCase): def test_widget_without_choices(self): w = LinkWidget() self.assertEqual(len(w.choices), 0) self.assertHTMLEqual(w.render('price', ''), """
          """) def test_widget(self): choices = ( ('test-val1', 'test-label1'), ('test-val2', 'test-label2'), ) w = LinkWidget(choices=choices) self.assertEqual(len(w.choices), 2) self.assertHTMLEqual(w.render('price', ''), """ """) self.assertHTMLEqual(w.render('price', None), """ """) self.assertHTMLEqual(w.render('price', 'test-val1'), """ """) 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', ''), """ """) 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', ''), """ """) 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): def test_widget(self): w = RangeWidget() self.assertEqual(len(w.widgets), 2) self.assertHTMLEqual(w.render('price', ''), """ - """) self.assertHTMLEqual(w.render('price', slice(5.99, 9.99)), """ - """) django-filter-0.11.0/tests/test_widgets.pyc0000644000076500000240000001415412410601743021472 0ustar carltonstaff00000000000000ó o#Tc@@s¼ddlmZddlmZddlmZddlmZmZddlm Z ddlm Z ddlm Z defd „ƒYZ d efd „ƒYZ d efd „ƒYZdS(i(tabsolute_import(tunicode_literals(tTestCase(t TextInputtSelect(t RangeWidget(t LinkWidget(tLookupTypeWidgettLookupTypeWidgetTestscB@seZd„Zd„ZRS(cC@s!|jtƒ tƒWdQXdS(N(t assertRaisest TypeErrorR(tself((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_widgets.pyttest_widget_requires_fieldscC@sˆtƒtdd d fƒg}t|ƒ}|j|jddƒdƒ|j|jddƒdƒ|j|jdddgƒdƒdS( NtchoicesuaubupriceuuÅ u2uã (uaua(ubub(RRRtassertHTMLEqualtrendertNone(R twidgetstw((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_widgets.pyttest_widget_renders (t__name__t __module__R R(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_widgets.pyR s tLinkWidgetTestscB@s5eZd„Zd„Zd„Zd„Zd„ZRS(cC@sBtƒ}|jt|jƒdƒ|j|jddƒdƒdS(Niupriceuu
            (Rt assertEqualtlenR RR(R R((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_widgets.pyttest_widget_without_choices-s cC@sŒd d f}td|ƒ}|jt|jƒdƒ|j|jddƒd ƒ|j|jddƒd ƒ|j|jddƒd ƒdS( Nu test-val1u test-label1u test-val2u test-label2R iupriceuu« (u test-val1u test-label1(u test-val2u test-label2(RRRR RRR(R R R((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_widgets.pyt test_widget2s cC@sVdddffdddffdf}td |ƒ}|j|jddƒdƒdS(NuAudiouvinyluVinylucduCDuVideouvhsuVHS TapeudvduDVDuunknownuUnknownR umediauu@ (uvinyluVinyl(ucduCD(uvhsuVHS Tape(udvduDVD(uunknownuUnknown(RRR(R R R((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_widgets.pyttest_widget_with_option_groupsLs   cC@s>d d d f}td|ƒ}|j|jddƒd ƒdS( Nuu ---------u test-val1u test-label1u test-val2u test-label2R upriceuï (uu ---------(u test-val1u test-label1(u test-val2u test-label2(RRR(R R R((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_widgets.pyttest_widget_with_blank_choicees  cC@s?tƒ}idd6}|j|idƒ}|j|dƒdS(Nu test-val1uprice(Rtvalue_from_datadictR(R Rtdatatresult((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_widgets.pyttest_widget_value_from_datadictts  (RRRRRRR (((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_widgets.pyR+s     tRangeWidgetTestscB@seZd„ZRS(cC@sgtƒ}|jt|jƒdƒ|j|jddƒdƒ|j|jdtddƒƒdƒdS(Niupriceuup - gö(\Âõ@g{®Gáú#@uŠ - (RRRRRRtslice(R R((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_widgets.pyR}s  (RRR(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_widgets.pyR!{sN(t __future__RRt django.testRt django.formsRRtdjango_filters.widgetsRRRRRR!(((sI/Users/carlton/Documents/Django-Stack/django-filter/tests/test_widgets.pytsPdjango-filter-0.11.0/tests/urls.py0000644000076500000240000000054712410601557017613 0ustar carltonstaff00000000000000from __future__ import absolute_import from __future__ import unicode_literals from django.conf.urls import patterns from django_filters.views import FilterView from .models import Book urlpatterns = patterns('', (r'^books-legacy/$', 'django_filters.views.object_filter', {'model': Book}), (r'^books/$', FilterView.as_view(model=Book)), ) django-filter-0.11.0/tests/urls.pyc0000644000076500000240000000117312410601744017750 0ustar carltonstaff00000000000000ó o#Tc@@sˆddlmZddlmZddlmZddlmZddlmZeddd ied 6fd ej d eƒfƒZ d S(i(tabsolute_import(tunicode_literals(tpatterns(t FilterViewi(tBookuu^books-legacy/$u"django_filters.views.object_filterumodelu^books/$tmodelN( t __future__RRtdjango.conf.urlsRtdjango_filters.viewsRtmodelsRtas_viewt urlpatterns(((sA/Users/carlton/Documents/Django-Stack/django-filter/tests/urls.pyts