Commits

Matthew Schinckel committed 8770588

Updated documentation.
Allowed for callable in instance_filters, and dict in filters.
Moved version number to seperate file.

  • Participants
  • Parent commits 17d4baf

Comments (0)

Files changed (6)

 django-filtered-form
 =====================
 
-Declarative way to define filters on fields on a django model form.
+
+---------------
+Installation
+---------------
+
+In your virtualenv, use ``pip install django-filteredform``.
+
+You don't need to install it into your ``settings.INSTALLED_APPS``, as it 
+does not provide any models or templates, only forms.
+
+---------------
+Usage
+---------------
+
+Declarative way to define filters on fields on a django model form::
 
     from django import forms
     from people.models import Person
             'units': 'company.units'
         }
         filters = {
-            'units': models.Q(is_active=True)
+            'units': models.Q(is_active=True),
+            'colours__in': ['red','blue','green']
         }
 
-There is also a version for FormSet.
+~~~~~~~~~~~~~~~~~~~~~
+``instance_filters``
+~~~~~~~~~~~~~~~~~~~~~
+``instance_filters`` are things that allow for relational filters to be applied.
+
+For instance, if you have a triple of models, ``Person``, ``Unit`` and ``Company``, 
+and every person and unit have a foreign key to a company, you can
+use an instance filter to easily select only the associated company's units for
+a queryset when viewing a person.
+
+Alternatively, you can supply a queryset method (that does not require arguments),
+for more filtering::
+
+    instance_filters = {
+        'units': 'company.units.active'
+    }
+
+~~~~~~~~~~~~~~~~~~~~~
+plain ``filters``
+~~~~~~~~~~~~~~~~~~~~~
+
+A more conventional filter structure, that allows you to supply a ``Q`` object, or
+a dict of key-value pairs, which will be passed to ``.filter()`` on the queryset.
+
+You can quite easily shoot yourself in the foot if your filter keys are not valid
+arguments for a filter function on that queryset.
+
+~~~~~~~~~~~~~~~~~~~~~
+FormSets
+~~~~~~~~~~~~~~~~~~~~~
+
+You can either create a form using this method, and then pass that to your formset
+class or factory. Or, you can have a formset class based on ``filtered_form.forms.FilteredFormSet``,
+which will also set up the queryset values on the empty form correctly, which is very
+useful if you are using dynamic forms.
+
+---------------
+Version History
+---------------
+
+~~~~~~~~
+1.0.1
+~~~~~~~~
+Improve documentation.
+
+Allow for a callable in the value of an ``instance_filter``.
+
+Allow for a dict in the value of a ``filter``.
+
+~~~~~~~~
+1.0
+~~~~~~~~
+Initial Release.

File filtered_form/VERSION

Empty file added.

File filtered_form/__init__.py

+import os
+__version__ = open(os.path.join(os.path.dirname(__file__), 'VERSION')).read()

File filtered_form/forms.py

 from django import forms
+from django.db.models import Q
 from django.core.exceptions import ObjectDoesNotExist
 
 class FilterMixin(object):
                 for segment in tokens[1:]:
                     source = getattr(source, segment)
                 if forms:
+                    # If the object is callable, then call it.
+                    # This means we can use queryset methods (that return a queryset).
+                    if callable(source):
+                        source = source()
                     for form in forms:
                         if field in form.fields:
                             form.fields[field].queryset = source
         for field, q_filter in self.filters.iteritems():
             for form in forms:
                 if field in form.fields:
-                    form.fields[field].queryset = form.fields[field].queryset.filter(q_filter)
+                    if isinstance(q_filter, Q):
+                        form.fields[field].queryset = form.fields[field].queryset.filter(q_filter)
+                    elif isinstance(q_filter, dict):
+                        form.fields[field].queryset = form.fields[field].queryset.filter(**q_filter)
     
 
 class FilteringForm(forms.ModelForm, FilterMixin):

File filtered_form/models.py

Empty file removed.
 from distutils.core import setup
 
+import filtered_form
+
 setup(
     name = "django-filtered-form",
-    version = "1.0",
+    version = filtered_form.__version__,
     description = "A Form that can have per-field queryset filters declaratively defined",
+    long_description = open('README.txt').read(),
     url = "http://bitbucket.org/schinckel/django-filtered-form",
     author = "Matthew Schinckel",
     author_email = "matt@schinckel.net",