Skip to main content

Django URL Filter provides a safe way to filter data via human-friendly URLs.

Project description

https://badge.fury.io/py/django-url-filter.svg https://readthedocs.org/projects/django-url-filter/badge/?version=latest https://drone.miki725.com/api/badges/miki725/django-url-filter/status.svg https://codecov.io/gh/miki725/django-url-filter/branch/master/graph/badge.svg

Django URL Filter provides a safe way to filter data via human-friendly URLs.

Overview

The main goal of Django URL Filter is to provide an easy URL interface for filtering data. It allows the user to safely filter by model attributes and also allows to specify the lookup type for each filter (very much like Django’s filtering system in ORM).

For example the following will retrieve all items where the id is 5 and title contains "foo":

example.com/listview/?id=5&title__contains=foo

In addition to basic lookup types, Django URL Filter allows to use more sophisticated lookups such as in or year. For example:

example.com/listview/?id__in=1,2,3&created__year=2013

Requirements

  • Python 2.7, 3.x, pypy or pypy3

  • Django 1.8+ (there are plans to support older Django versions)

  • Django REST Framework 2 or 3 (only if you want to use DRF integration)

Installing

Easiest way to install this library is by using pip:

$ pip install django-url-filter

Usage Example

To make example short, it demonstrates Django URL Filter integration with Django REST Framework but it can be used without DRF (see below).

from url_filter.integrations.drf import DjangoFilterBackend


class UserViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_backends = [DjangoFilterBackend]
    filter_fields = ['username', 'email']

Alternatively filterset can be manually created and used directly to filter querysets:

from django.http import QueryDict
from url_filter.filtersets import ModelFilterSet


class UserFilterSet(ModelFilterSet):
    class Meta(object):
        model = User

query = QueryDict('email__contains=gmail&joined__gt=2015-01-01')
fs = UserFilterSet(data=query, queryset=User.objects.all())
filtered_users = fs.filter()

Above will automatically allow the use of all of the Django URL Filter features. Some possibilities:

# get user with id 5
example.com/users/?id=5

# get user with id either 5, 10 or 15
example.com/users/?id__in=5,10,15

# get user with id between 5 and 10
example.com/users/?id__range=5,10

# get user with username "foo"
example.com/users/?username=foo

# get user with username containing case insensitive "foo"
example.com/users/?username__icontains=foo

# get user where username does NOT contain "foo"
example.com/users/?username__icontains!=foo

# get user who joined in 2015 as per user profile
example.com/users/?profile__joined__year=2015

# get user who joined in between 2010 and 2015 as per user profile
example.com/users/?profile__joined__range=2010-01-01,2015-12-31

# get user who joined in after 2010 as per user profile
example.com/users/?profile__joined__gt=2010-01-01

Features

  • Human-friendly URLs

    Filter querystring format looks very similar to syntax for filtering in Django ORM. Even negated filters are supported! Some examples:

    example.com/users/?email__contains=gmail&joined__gt=2015-01-01
    example.com/users/?email__contains!=gmail  # note !
  • Related models

    Support related fields so that filtering can be applied to related models. For example:

    example.com/users/?profile__nickname=foo
  • Decoupled filtering

    How URLs are parsed and how data is filtered is decoupled. This allows the actual filtering logic to be decoupled from Django hence filtering is possible not only with Django ORM QuerySet but any set of data can be filtered (e.g. SQLAlchemy query objects) assuming corresponding filtering backend is implemented.

  • Usage-agnostic

    This library decouples filtering from any particular usage-pattern. It implements all the basic building blocks for creating filtersets but it does not assume how they will be used. To make the library easy to use, it ships with some integrations with common usage patterns like integration with Django REST Framework. This means that its easy to use in custom applications with custom requirements (which is probably most of the time!)

History

0.3.15 (2022-02-17)

0.3.15 (2020-02-10)

  • Fixes date lookup when using Django ORM. See #92.

0.3.14 (2019-10-30)

  • Using CharField for regex filters. See #90.

  • SQLAlchemyFilterBackend does not join models if already join path is partially joined already.

  • SQLAlchemyFilterBackend joins when selectinjoin is used.

0.3.13 (2019-07-28)

  • Fixing iregex documentation in DRF coreapi integration.

0.3.12 (2019-01-24)

  • Adding support for FilterSet.Meta.fields == '__all__' which is useful in DRF integration. See #39.

0.3.11 (2018-12-06)

  • Not modifying queryset in Django backend if no filters were applied. See #73.

0.3.10 (2018-11-14)

  • Only running distinct on queryset when one of filters is on one-to-many relation. This should help with performance. See #26.

0.3.9 (2018-11-12)

  • Adding iin form field overwrite for SQLAlchemy as otherwise by default iin lookup is not validated correctly.

0.3.8 (2018-08-08)

  • Fixed SQLAlchemyFilterBackend by not joining nested models when they are already eager loaded via query.options().

0.3.7 (2018-07-27)

  • Added StrictModel.empty which is new default. It returns empty queryset when any filter validations fail.

  • Fixed in lookup. Previously if any of the items were invalid whole filter would fail and depending on strict mode would either return all results, no results or will raise exception. Now in StrictMode.empty and StrictMode.drop any invalid items are ignored which will filter results for valid items. See #63.

  • Added ability in ModelFilterSet to customize filter names by providing extra_kwargs with field source. See #66.

0.3.6 (2018-07-23)

  • Added support for extra_kwargs in ModelFilterSet.Meta.

  • Added CoreAPIURLFilterBackend which enables documented filters in swagger docs.

  • Added iin lookup in plain and sqlalchemy backends.

  • Fixing inconsistency between plain and Django week_day lookup. Now both are consistent with 1-Monday and 7-Sunday.

0.3.5 (2018-02-27)

  • Django 2 support.

  • Using tox-travis for travis builds.

  • Fixed negated queries in Django backend. Previously negation did NOT (condition1 and condition2) vs expected NOT condition1 and NOT condition2. See #53.

0.3.4 (2017-08-17)

  • Py36 compatibility by switching to enum-compat from enum34

  • Improvement to README by including imports in code examples

  • Defaulting SQLAlchemyModelFilterSet to use SQLAlchemyFilterBackend

  • Defaulting PlainModelFilterSet to use PlainFilterBackend

  • Using universal wheels for distribution

0.3.3 (2017-06-15)

  • Fixed bug which did not allow to use SQLAlchemy backend fully without having django.contrib.contenttypes in installed apps. See #36.

  • Improved SQLAlchemy versions compatibility.

  • Added URLFilterBackend alias in DRF integration for backend to reduce confusion with DjangoFilterBackend as in url filter core backend.

0.3.2 (2017-05-19)

  • Fixed plain backend to return list in Python 3 vs filter() generator which is not compatible with Django pagination since it requires len() to be implemented.

0.3.1 (2017-05-18)

  • Fixed bug where default filters were used in root filtersets. As a result additional querystring parameters were validation which broke other functionality such as pagination.

0.3.0 (2017-01-26)

  • Added plain objects filtering support. More in docs and GitHub issue #8.

  • Added CallableFilter which allows to implement custom filters.

  • Normalizing to DRF’s ValidationError when using StrictMode.Fail since filterset raises Django’s ValidationError which caused 500 status code.

  • Fixes ModelFilterSet automatic introspection to ignore GenericForeignKey since they dont have form fields associated with them. See #20.

  • Releasing with wheels.

0.2.0 (2015-09-12)

  • Added SQLAlchemy support.

  • FilterSet instances have much more useful __repr__ which shows all filters at a glance. For example:

    >>> PlaceFilterSet()
    PlaceFilterSet()
      address = Filter(form_field=CharField, lookups=ALL, default_lookup="exact", is_default=False)
      id = Filter(form_field=IntegerField, lookups=ALL, default_lookup="exact", is_default=True)
      name = Filter(form_field=CharField, lookups=ALL, default_lookup="exact", is_default=False)
      restaurant = RestaurantFilterSet()
        serves_hot_dogs = Filter(form_field=BooleanField, lookups=ALL, default_lookup="exact", is_default=False)
        serves_pizza = Filter(form_field=BooleanField, lookups=ALL, default_lookup="exact", is_default=False)
        waiter = WaiterFilterSet()
          id = Filter(form_field=IntegerField, lookups=ALL, default_lookup="exact", is_default=True)
          name = Filter(form_field=CharField, lookups=ALL, default_lookup="exact", is_default=False)

0.1.1 (2015-09-06)

  • Fixed installation issue where not all subpackages were installed.

0.1.0 (2015-08-30)

  • First release on PyPI.

Credits

Development Lead

Contributors

License

The MIT License (MIT)

Copyright (c) 2015, Miroslav Shubernetskiy

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

suap-duf-0.3.16.tar.gz (46.9 kB view details)

Uploaded Source

Built Distribution

suap_duf-0.3.16-py2.py3-none-any.whl (40.0 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file suap-duf-0.3.16.tar.gz.

File metadata

  • Download URL: suap-duf-0.3.16.tar.gz
  • Upload date:
  • Size: 46.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.1 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.2

File hashes

Hashes for suap-duf-0.3.16.tar.gz
Algorithm Hash digest
SHA256 a0d338c02a3cdeae964ea48e795ff18cf1bd28d34245d5d0b8feff1a144bb492
MD5 60705c35beb024111619f9e57e0d552c
BLAKE2b-256 9d68aceadd9a064a5c24f67570c381712b2fe1c0824f156d0301b86837187525

See more details on using hashes here.

File details

Details for the file suap_duf-0.3.16-py2.py3-none-any.whl.

File metadata

  • Download URL: suap_duf-0.3.16-py2.py3-none-any.whl
  • Upload date:
  • Size: 40.0 kB
  • Tags: Python 2, Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.1 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.9.2

File hashes

Hashes for suap_duf-0.3.16-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 d0c2b293f104f46891eb2b798ee7ee567b20a8781e52c005d6094a4b65f3975d
MD5 6d2d017ebed0b976c7d1919779a5aea1
BLAKE2b-256 a9c2a9d2a4d35222c6ee9dd8badc99281d36ed2e8457e128d49650a2a908c9c7

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page