alex / django-filter
- Source
- Commits
- Network (15)
- Issues (10)
- Downloads (5)
- Wiki (1)
- Graphs
-
Branch:
master
-
Document how django-filter works with django-pagination
3 comments Created 4 months ago by bartTCThey both work well together, it took me a while to fiddle it out. Based on the example in the docs:
{% block content %} <form action="" method="get"> {{ f.form.as_p }} <input type="submit" /> </form> {% autopaginate f.qs 40 as filter_list %} {% for obj in filter_list %} {{ obj.name }} - ${{ obj.price }}<br /> {% endfor %} {% paginate %} {% endblock %}The key is that you have to use pagination's as argument.
Comments
-
hi alex, great project!
i've been trying various things for a while, but i can't seem to find a decent solution to filter tags from django-tagging with django-filter.
have you considered this? could you point me in the right direction, code-wise?Comments
The right solution is to make a "TagFilter", I might write up a prototype if I have the time, but basically look at some of the Filters inlcuded in django-filter now for an example of what it might look like.
cool, thanks.
so far, i copied the AllValuesFilter and extended the MultipleChoiceFilter:
class TagFilter(MultipleChoiceFilter): @property def field(self): #qs = self.model._default_manager.distinct().order_by(self.name).values_list(self.name, flat=True) #returns list of unicode strings, similar to above qs = self.model.tags.split() self.extra['choices'] = [(o, o) for o in qs] return super(TagFilter, self).fieldthis displays properly, but will i have to modify BaseFilterSet to deal with tag matching?
Now you need to override the filter() method on TagFilter, to do the actual filtering. If you look at the parameters it gets it should be obvious what you need to do :)
thanks for your help, alex!
ok, this seems to work on a model field that has been registered with 'tagging.register':class TagFilter(MultipleChoiceFilter): @property def field(self): qs = self.model.tags.split() self.extra['choices'] = [(o, o) for o in qs] return super(TagFilter, self).field def filter(self, qs, value): value_flat = ' '.join(value) if value_flat: return qs.model.tagged.with_all(value_flat) else: return qsunfortunately, it doesn't play nice with the other fields in the FilterSet (which are ignored); i'm assuming because there is no
qs.filter(**…? is it possible fortagged.with_allto work with aqs.filter? or maybe i'm going about this the wrong way.Yeah, filter should return a QuerySet that is just the one passed to it filtered down. Perhaps the best bet is to make the tag filter the first filter on your FilterSet.
ah, i missed this bit in the django-tagging docs:
``with_all(tags, queryset=None)`` -- creates a ``QuerySet`` containing model instances which are tagged with *all* the given tags. If a ``queryset`` argument is provided, it will be used as the basis for the resulting ``QuerySet``.http://code.google.com/p/django-tagging/source/browse/trunk/docs/overview.txt
changing the relevant line in TagFilter to the following seems to work:
return qs.model.tagged.with_all(value_flat, qs)cool. thanks for your help!
-
Seems like their it would be possible to enhance this tool to allow for the chaining of filters to allow the results to be refined/constrained. This might be done by serializing the form data from one submit, and passing it as a hidden field back in the next form. The presence of this previous form could be used to create a filtered queryset before then filtering again with the current form's contents?
What do you think? I'm still learning at this level, but I could fork and try to implement if you think its a worthwhile addition.
Comments
This is definitely possible with the current architecture, you'd just need to presist the filtering params. That being said I don't think this is something that should be in django-filter itself. I'm not going to close this yet though (because I can't figure out how to reopen tickets :P)
-
Support for displaying related object fields
2 comments Created about 1 month ago by subsumeThere is currently nothing in place on the display side that will respect any querying done against related fields.
Let's take this basic relationship:
class Company(models.Model): name = models.CharField() address = models.ManyToManyField('below.Address') class Address(models.Model): zip = models.CharField() telephone = models.CharField()With related fields, I could grab all companies within a particular zip code, however, I'm still stuck displaying information strictly on the primary model of a FilterSet. If I wanted to grab all telephone numbers with the zip code, I would have to a) re-execute my querying somewhere after django-filter is done and grab the zips myself b) reorient my whole approach and create a filter against the Address model (but now I'm stuck with the same problem on a different model).
I've already got this working (albeit, outside of django-filter). Right now it works like:
(Deprecated, See comment below)
- User submits a form much like that which django-filters provides
- The querying is done internally, and records are matched. At this step, django-filter current work is done.
- Check for related objects in my "display_fields" (i imagine it would be a item in Meta)
- If I find them, I group them into "bundles"
- I organize my initial querying into similar bundles
- I loop through the original queryset
- For each item, I check the relations against the display field, if I find one, I grab the related objects. If I find a querying bundle, I respect whatever that query was as I do this
- I throw the result into a tuple, the first item of which is my original model.
- If my querying turned up a set of objects, the values_list is then dumped in instead of the object value (maybe two telephone numbers were matched). Alternately, you could create another tuple for the same object and add them both.
I'm looking for direction on whether this is a goal of django-filters. Alternatives I see are:
1. return a subclass of a QuerySet which has these field values
2. return a list of tuples that contains each record, and any additional valuse tacked-onComments
Upon working with extra() a bit, I'm convinced the best approach would be to simply include relations listed in Meta.display_fields in extra(select={'foo':...}). One obstacle would be displaying fields on tables that weren't part of querying, but it seems do-able.
I've got this more or less working. All it takes is some work with extra() to get the related fields tacked onto the original QuerySet. If the user is willing to do that, then all that's missing is a way to display arbitrary fields. Maybe a FilterSet and a DisplaySet?
- User submits a form much like that which django-filters provides
-
Make lookup type a class attribute on the Filter
0 comments Created about 1 month ago by fivethreeoTo make overriding of lookup types easier
class Filter(object): creation_counter = 0 field_class = forms.Field lookup_type = 'exact' def __init__(self, name=None, label=None, widget=None, action=None, lookup_type=None, required=False, **kwargs): self.name = name self.label = label if action: self.filter = action self.lookup_type = lookup_type or self.lookup_type self.widget = widget self.required = required self.extra = kwargsComments
-
There is no way currently to evaluate two filters together (AND vs OR on the relations queried):0
Given
class Organization(models.Model): name = models.CharField(..) class Location(models.Model): organization = models.ForeignKey(Organization) zip_code = models.PositiveIntegerfield(...) open_saturday = models.BooleanField(...)A django filter oriented around Organization but with fields for 'zip_code' and 'open_saturday' cannot give you all organization within a particular zip code who are also open saturday.
One possible approach would be to create a filter_together option for Meta, which would be a list of tuples of field name bundles. If there is a way to garner a Q object from a queryset, one could loop through these bundles compiling Q objects and then filter them together. If not, perhaps an as_q() method could be added to a filter which returns a Q object instead.
Like my other Issue in this realm, I really don't mind submitting code if a design decision favors things like this.
Comments
-
Allow CharField's with choice to be overriden using filter_overrides
1 comment Created about 1 month ago by subsumeThis line seems to prevent anything with 'choices' to be overridable with filter_overrides.
http://github.com/alex/django-filter/blob/master/django_filters/filterset.py#L277
Comments
-
File "/home/skyl/Desktop/code/pinax/pinax-dev/lib/python2.6/site-packages/django_filters/tests/init.py", line ?, in django_filters.tests.test.filter_tests
Failed example:
print F().formException raised:
Traceback (most recent call last): File "/home/skyl/Desktop/code/pinax/pinax-dev/lib/python2.6/site-packages/django/test/_doctest.py", line 1267, in __run compileflags, 1) in test.globs File "<doctest django_filters.tests.__test__.filter_tests[114]>", line 1, in <module> print F().form File "/home/skyl/Desktop/code/pinax/pinax-dev/lib/python2.6/site-packages/django_filters/filterset.py", line 184, in __init__ self.filters = deepcopy(self.base_filters) File "/usr/lib/python2.6/copy.py", line 173, in deepcopy y = copier(memo) File "/home/skyl/Desktop/code/pinax/pinax-dev/lib/python2.6/site-packages/django/utils/datastructures.py", line 77, in __deepcopy__ for key, value in self.iteritems()]) File "/usr/lib/python2.6/copy.py", line 189, in deepcopy y = _reconstruct(x, rv, 1, memo) File "/usr/lib/python2.6/copy.py", line 338, in _reconstruct state = deepcopy(state, memo) File "/usr/lib/python2.6/copy.py", line 162, in deepcopy y = copier(x, memo) File "/usr/lib/python2.6/copy.py", line 255, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "/usr/lib/python2.6/copy.py", line 162, in deepcopy y = copier(x, memo) File "/usr/lib/python2.6/copy.py", line 255, in _deepcopy_dict y[deepcopy(key, memo)] = deepcopy(value, memo) File "/usr/lib/python2.6/copy.py", line 181, in deepcopy rv = reductor(2) File "/home/skyl/Desktop/code/pinax/pinax-dev/lib/python2.6/site-packages/django/db/models/query.py", line 153, in __getstate__ len(self) File "/home/skyl/Desktop/code/pinax/pinax-dev/lib/python2.6/site-packages/django/db/models/query.py", line 173, in __len__ self._result_cache = list(self.iterator()) File "/home/skyl/Desktop/code/pinax/pinax-dev/lib/python2.6/site-packages/django/db/models/query.py", line 288, in iterator for row in self.query.results_iter(): File "/home/skyl/Desktop/code/pinax/pinax-dev/lib/python2.6/site-packages/django/db/models/sql/query.py", line 205, in results_iter for rows in self.execute_sql(MULTI): File "/home/skyl/Desktop/code/pinax/pinax-dev/lib/python2.6/site-packages/django/db/models/sql/query.py", line 1820, in execute_sql cursor.execute(sql, params) File "/home/skyl/Desktop/code/pinax/pinax-dev/lib/python2.6/site-packages/django/db/backends/sqlite3/base.py", line 170, in execute return Database.Cursor.execute(self, query, params) OperationalError: no such table: tests_usera few like this, tests_book.
Comments
I did see this, but I suspect this is ultimately a bug in Pinax. This app is one case where a new app stores the models and it isn't in INSTALLED_APPS for the test environment. Will need to dig deeper. There may need to be action in this app, but I'm not sure what it is yet.
This was an issue in Pinax and fixed http://github.com/pinax/pinax/commit/717567438b96be9d8311a64c1b29d7cbeda33416 (please close)
-
Looks like it's something related to testing under different databases, and having results in different orders. Enforce ordering on models and tests, or make test assertions ignore the order.
The output:
........................................F.E..........F....F.............................
FAIL: Doctest: django_filters.tests.test.filter_tests
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/Django-1.1.1-py2.6.egg/django/test/_doctest.py", line 2180, in runTestraise self.failureException(self.format_failure(new.getvalue()))AssertionError: Failed doctest test for django_filters.tests.test.filter_tests
File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django_filter-0.5.2-py2.6.egg/django_filters/tests/init.py", line unknown line number, in filter_testsFile "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django_filter-0.5.2-py2.6.egg/django_filters/tests/init.py", line ?, in django_filters.tests.test.filter_tests
Failed example:
f.qsExpected:
[<User: alex>, <User: aaron>, <User: jacob>]Got:
[<User: aaron>, <User: alex>, <User: jacob>]File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django_filter-0.5.2-py2.6.egg/django_filters/tests/init.py", line ?, in django_filters.tests.test.filter_tests
Failed example:
f.qsExpected:
[<User: alex>, <User: aaron>, <User: jacob>]Got:
[<User: aaron>, <User: alex>, <User: jacob>]File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django_filter-0.5.2-py2.6.egg/django_filters/tests/init.py", line ?, in django_filters.tests.test.filter_tests
Failed example:
f.qsExpected:
[<User: alex>, <User: aaron>]Got:
[<User: aaron>, <User: alex>]File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django_filter-0.5.2-py2.6.egg/django_filters/tests/init.py", line ?, in django_filters.tests.test.filter_tests
Failed example:
f.qsExpected:
[<User: alex>, <User: aaron>]Got:
[<User: aaron>, <User: alex>]File "/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/django_filter-0.5.2-py2.6.egg/django_filters/tests/init.py", line ?, in django_filters.tests.test.filter_tests
Failed example:
f.qsExpected:
[<User: alex>, <User: aaron>, <User: jacob>]Got:
[<User: aaron>, <User: alex>, <User: jacob>]Ran 88 tests in 3.208s
FAILED (failures=3, errors=1)
Comments
-
Hi,
Thanks for this great django contribution!I ran into one minor problem. It seems that FilterSet does not find USStateFields. When I add the model field as a class variable to FilterSet, it appears, but is out of order - it appears after the fields it can find.
Thanks
Comments





Very, very useful. Thank you.
I'd suggest to document how this works with django-sorting too. Unfortunately django-sorting needs to go before pagination and doesn't support the 'as' keyword, so we are not able to do something like this:
Filed upstream at http://github.com/directeur/django-sorting/issues/#issue/4.
Get this issue when I try the above.
http://code.google.com/p/django-pagination/issues/detail?id=59#c0
Any ideas about what it might be?