PK½•IÁ_(y‡‡plugs_filter/decorators.py""" Plugs Core Decorators """ from plugs_filter.filters import AutoFilters from plugs_filter.filtersets import FilterSet def get_view_model(cls): """ Get the model to use in the filter_class by inspecting the queryset or by using a declared auto_filters_model """ msg = 'When using get_queryset you must set a auto_filters_model field in the viewset' if cls.queryset is not None: return cls.queryset.model else: assert hasattr(cls, 'auto_filters_model'), msg return cls.auto_filters_model def auto_filters(cls): """ Adds a dynamic filterclass to a viewset with all auto filters available for the field type that are declared in a tuple auto_filter_fields @auto_filters def class(...): ... auto_filters_fields('id', 'location', 'category') """ msg = 'Viewset must have auto_filters_fields set when using auto_filters decorator' assert hasattr(cls, 'auto_filters_fields'), msg dict_ = {} for auto_filter in getattr(cls, 'auto_filters_fields'): dict_[auto_filter] = AutoFilters(name=auto_filter) # create the inner Meta class and then the filter class view_model = get_view_model(cls) dict_['Meta'] = type('Meta', (object, ), {'model': view_model, 'fields': ()}) filter_class = type('DynamicFilterClass', (FilterSet, ), dict_) cls.filter_class = filter_class return cls PKJ†2J°‰¹¹plugs_filter/utils.py""" Plugs core utils """ from django.db.models import fields LOOKUP_TABLE = { # for now we are going to assume that foreign keys are always ints fields.related.ForeignKey : ['gt', 'lt', 'gte', 'lte', 'in'], fields.AutoField : ['gt', 'lt', 'gte', 'lte', 'in'], fields.IntegerField : ['gt', 'lt', 'in'], fields.DecimalField : ['gt', 'lt', 'in'], fields.CharField : ['contains', 'icontains'], fields.DateTimeField: ['gt', 'lt'], fields.BooleanField: ['in'], fields.TextField : ['contains', 'icontains'] } def lookups_for_field(model_field): """ Returns lookups """ return class_lookups(model_field) def get_field_lookups(field_type, nullable): """ Return lookup table value and append isnull if this is a nullable field """ return LOOKUP_TABLE.get(field_type) + ['isnull'] if nullable else LOOKUP_TABLE.get(field_type) def match_field(field_class): """ Iterates the field_classes and returns the first match """ for cls in field_class.mro(): if cls in list(LOOKUP_TABLE.keys()): return cls # could not match the field class raise Exception('{0} None Found '.format(field_class)) def class_lookups(model_field): """ Return list of available lookups for the passed in (model) field type """ field_class = type(model_field) field_type = match_field(field_class) return get_field_lookups(field_type, model_field.null) PK"½•IhÃGWplugs_filter/filters.py""" Filters """ from django_filters.filters import Filter class AutoFilters(Filter): """ Automatically adds valid filters for field type """ pass class DynamicFilters(Filter): """ Creates a list of filters from the passed in attach list """ pass PK\‡2Jµ`³èplugs_filter/__init__.py__version__ = '0.1.1' PK½•I o…ÄÄplugs_filter/filtersets.py""" Filtering """ from django.utils import six from django.db.models.constants import LOOKUP_SEP from django_filters import filterset from plugs_filter.filters import AutoFilters from plugs_filter import utils class Meta(filterset.FilterSetMetaclass): """ Metaclass for Filtersets How AutoFilters are declared: def SomeFilterClass(FilterSet): location = AutoFilters(name='location') class Meta: model = models.Experience fields = () Optionally you can drop some of the default auto filters by using drop ... location = AutoFilters(name='location', drop=['in', 'gte']) ... """ def attach_core_filters(cls): """ Attach core filters to filterset """ opts = cls._meta for name, filter_ in six.iteritems(cls.base_filters.copy()): if isinstance(filter_, AutoFilters): field = filterset.get_model_field(opts.model, filter_.name) filter_exclusion = filter_.extra.pop('drop', []) for lookup_expr in utils.lookups_for_field(field): if lookup_expr not in filter_exclusion: new_filter = cls.filter_for_field(field, filter_.name, lookup_expr) filter_name = LOOKUP_SEP.join([name, lookup_expr]) cls.base_filters[filter_name] = new_filter def __new__(cls, name, bases, attrs): """ Overring the object construction """ new_class = super(Meta, cls).__new__(cls, name, bases, attrs) cls.attach_core_filters(new_class) return new_class class FilterSet(six.with_metaclass(Meta, filterset.FilterSet)): pass PK[œ•I×ió;††plugs_filter/runtests.py#!/usr/bin/env python import os import sys import django from django.conf import settings from django.test.utils import get_runner if __name__ == "__main__": os.environ['DJANGO_SETTINGS_MODULE'] = 'tests.test_settings' django.setup() TestRunner = get_runner(settings) test_runner = TestRunner() failures = test_runner.run_tests(["tests"]) sys.exit(bool(failures)) PKˈ2JZ»V¶‰‰,plugs_filter-0.1.1.dist-info/DESCRIPTION.rst============================= Plugs Filter ============================= .. image:: https://badge.fury.io/py/plugs-filter.png :target: https://badge.fury.io/py/plugs-filter .. image:: https://travis-ci.org/ricardolobo/plugs-filter.png?branch=master :target: https://travis-ci.org/ricardolobo/plugs-filter Your project description goes here Documentation ------------- The full documentation is at https://plugs-filter.readthedocs.io. Quickstart ---------- Install Plugs Filter:: pip install plugs-filter Add it to your `INSTALLED_APPS`: .. code-block:: python INSTALLED_APPS = ( ... 'plugs_filter.apps.PlugsFilterConfig', ... ) Add Plugs Filter's URL patterns: .. code-block:: python from plugs_filter import urls as plugs_filter_urls urlpatterns = [ ... url(r'^', include(plugs_filter_urls)), ... ] Features -------- * TODO Running Tests ------------- Does the code actually work? :: source /bin/activate (myenv) $ pip install tox (myenv) $ tox Credits ------- Tools used in rendering this package: * Cookiecutter_ * `cookiecutter-djangopackage`_ .. _Cookiecutter: https://github.com/audreyr/cookiecutter .. _`cookiecutter-djangopackage`: https://github.com/pydanny/cookiecutter-djangopackage History ------- 0.1.1 (2017-01-18) ++++++++++++++++++ * First release on PyPI. PKˈ2JŸ* ö··*plugs_filter-0.1.1.dist-info/metadata.json{"classifiers": ["Development Status :: 3 - Alpha", "Framework :: Django", "Framework :: Django :: 1.9", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Natural Language :: English", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5"], "extensions": {"python.details": {"contacts": [{"email": "ricardolobo@soloweb.pt", "name": "Ricardo Lobo", "role": "author"}], "document_names": {"description": "DESCRIPTION.rst"}, "project_urls": {"Home": "https://github.com/ricardolobo/plugs-filter"}}}, "extras": [], "generator": "bdist_wheel (0.26.0)", "keywords": ["plugs-filter"], "license": "MIT", "metadata_version": "2.0", "name": "plugs-filter", "run_requires": [{"requires": ["django-filter (==0.13.0)"]}], "summary": "Your project description goes here", "version": "0.1.1"}PKˈ2J&•|­ *plugs_filter-0.1.1.dist-info/top_level.txtplugs_filter PKˈ2Jìndªnn"plugs_filter-0.1.1.dist-info/WHEELWheel-Version: 1.0 Generator: bdist_wheel (0.26.0) Root-Is-Purelib: true Tag: py2-none-any Tag: py3-none-any PKˈ2Jsò-Ù­­%plugs_filter-0.1.1.dist-info/METADATAMetadata-Version: 2.0 Name: plugs-filter Version: 0.1.1 Summary: Your project description goes here Home-page: https://github.com/ricardolobo/plugs-filter Author: Ricardo Lobo Author-email: ricardolobo@soloweb.pt License: MIT Keywords: plugs-filter Platform: UNKNOWN Classifier: Development Status :: 3 - Alpha Classifier: Framework :: Django Classifier: Framework :: Django :: 1.9 Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Natural Language :: English Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Requires-Dist: django-filter (==0.13.0) ============================= Plugs Filter ============================= .. image:: https://badge.fury.io/py/plugs-filter.png :target: https://badge.fury.io/py/plugs-filter .. image:: https://travis-ci.org/ricardolobo/plugs-filter.png?branch=master :target: https://travis-ci.org/ricardolobo/plugs-filter Your project description goes here Documentation ------------- The full documentation is at https://plugs-filter.readthedocs.io. Quickstart ---------- Install Plugs Filter:: pip install plugs-filter Add it to your `INSTALLED_APPS`: .. code-block:: python INSTALLED_APPS = ( ... 'plugs_filter.apps.PlugsFilterConfig', ... ) Add Plugs Filter's URL patterns: .. code-block:: python from plugs_filter import urls as plugs_filter_urls urlpatterns = [ ... url(r'^', include(plugs_filter_urls)), ... ] Features -------- * TODO Running Tests ------------- Does the code actually work? :: source /bin/activate (myenv) $ pip install tox (myenv) $ tox Credits ------- Tools used in rendering this package: * Cookiecutter_ * `cookiecutter-djangopackage`_ .. _Cookiecutter: https://github.com/audreyr/cookiecutter .. _`cookiecutter-djangopackage`: https://github.com/pydanny/cookiecutter-djangopackage History ------- 0.1.1 (2017-01-18) ++++++++++++++++++ * First release on PyPI. PKˈ2JVñÃ!ôô#plugs_filter-0.1.1.dist-info/RECORDplugs_filter/__init__.py,sha256=ls1camlIoMxEZz9gSkZ1OJo-MXqHWwKPtdPbZJmwp7E,22 plugs_filter/decorators.py,sha256=y-Y0dgnb9kcC_1fHhSdY7L0klKDrQymThjN7GMxVJko,1415 plugs_filter/filters.py,sha256=nqLxrOUfM3JZcob9oXFrCDyM56_Z1fd3VOv_29Cz_p8,281 plugs_filter/filtersets.py,sha256=s-9fUGni8Vgrxtx0xjWg1GozkEJWkT6lQ_fX7FvJvwg,1732 plugs_filter/runtests.py,sha256=x9CYKK30PzZ6V9DpJSqxT95606k5qgdR7FWPqOz3B6E,390 plugs_filter/utils.py,sha256=P_3f8YdBAl3jwGgeMkcJp8j-XqlZIwR1c3kOIn4f1Ek,1465 plugs_filter-0.1.1.dist-info/DESCRIPTION.rst,sha256=3U7dP3T0z8BO5tz5j6GMkvLM2uXY9vtTc9lNPsH-MAE,1417 plugs_filter-0.1.1.dist-info/METADATA,sha256=Skp-NH7XyvxEaGV9Ajg2wV4qKc9gCxB_-uVDD9GAo4k,2221 plugs_filter-0.1.1.dist-info/RECORD,, plugs_filter-0.1.1.dist-info/WHEEL,sha256=GrqQvamwgBV4nLoJe0vhYRSWzWsx7xjlt74FT0SWYfE,110 plugs_filter-0.1.1.dist-info/metadata.json,sha256=pPIG5zfCnPo8i2tFa6VZ8UQkQ7Ropa-sM4vlTu_8JWQ,951 plugs_filter-0.1.1.dist-info/top_level.txt,sha256=5TywoozkYbTcug3qYZQNG-VC3_X5TTMlI81aEH-cDCs,13 PK½•IÁ_(y‡‡plugs_filter/decorators.pyPKJ†2J°‰¹¹¿plugs_filter/utils.pyPK"½•IhÃGW« plugs_filter/filters.pyPK\‡2Jµ`³èù plugs_filter/__init__.pyPK½•I o…ÄÄE plugs_filter/filtersets.pyPK[œ•I×ió;††Aplugs_filter/runtests.pyPKˈ2JZ»V¶‰‰,ýplugs_filter-0.1.1.dist-info/DESCRIPTION.rstPKˈ2JŸ* ö··*Ðplugs_filter-0.1.1.dist-info/metadata.jsonPKˈ2J&•|­ *Ïplugs_filter-0.1.1.dist-info/top_level.txtPKˈ2Jìndªnn"$ plugs_filter-0.1.1.dist-info/WHEELPKˈ2Jsò-Ù­­%Ò plugs_filter-0.1.1.dist-info/METADATAPKˈ2JVñÃ!ôô#Â)plugs_filter-0.1.1.dist-info/RECORDPK ¢÷-