This function is designed to make it easier to specify client-side query filtering options using JSON. Django has a great set of query operators as part of its database API. However, there's no way I know of to specify them in a way that's serializable, which means they can't be created on the client side or stored.
`build_query_filter_from_spec()` is a function that solves this problem by describing query filters using a vaguely LISP-like syntax. Query filters consist of lists with the filter operator name first, and arguments following. Complicated query filters can be composed by nesting descriptions. Read the doc string for more information.
To use this function in an AJAX application, construct a filter description in JavaScript on the client, serialize it to JSON, and send it over the wire using POST. On the server side, do something like:
> `from django.utils import simplejson`
> `filterString = request.POST.get('filter', '[]')`
> `filterSpec = simplejson.loads(filterString)`
> `q = build_query_filter_from_spec(filterSpec)`
> `result = Thing.objects.filter(q)`
You could also use this technique to serialize/marshall a query and store it in a database.
- filter
- ajax
- json
- database
- query
Disclaimer: I'm not the world's greatest programmer, so there may be better ways to do this, but it works for me (feel free to offer your improvements, though!).
Basically, this will pad an integer with leading zeros and return a string representation. User it like this:
{% forloop.counter|leading_zeros:"5" %}
...where "5" is the number of desired digits. In this case, if it was the 12th time through the forloop, the filter would return "00012".
Why do this? Either for alignment, such as in tables, or for aesthetics -- for an example, see [Shaun Inman's comment section](http://shauninman.com/archive/2007/11/16/mobilesafari_view_source).
I've been working on a project where I realized that I wanted to call methods on Python objects *with arguments* from within a Django template.
As a silly example, let's say your application maintains users and "permissions" that have been granted to them. Say that permissions are open-ended, and new ones are getting defined on a regular basis. Your `User` class has a `check_permission(p)` method that return `True` if the user has been granted the permission `p`.
You want to present all the users in a table, with one row per user. You want to each permission to be presented as a column in the table. A checkmark will appear in cells where a user has been granted a particular permission. Normally, in order to achieve this, you'd need to cons up some sort of list-of-dicts structure in Python and pass that as a context argument. Ugh!
Here's how you'd use the `method`, `with`, and `call` filters to invoke the `check_permission` method from within your template. (Assume that you've provided `users` and `permissions` as context variables, with a list of user and permission objects, respectively.)
<table>
<tr>
<th></th>
{% for p in permissions %}
<th>{{ p.name }}</th>
{% endfor %}
</tr>
{% for u in users %}
<tr>
<td>{{ u.name }}</td>
{% for p in permissions %}
<td>
{% if user|method:"check_permission"|with:p|call" %}X{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
The `call_with` method is a shortcut for single-argument invocation; for example, we could have re-written the above as
{% if user|method:"check_permission"|call_with:p %}...{% endif %}
Anyway, this has been useful for me. Hope it's helpful for others!
--chris
P.S., tip o' the cap to Terry Weissman for helping me polish the rough edges!
- filter
- filters
- function
- object
- method
A simple template filter for taking a list and humanizing it, converting:
`["foo", "bar"]` to `"foo and bar"`
`["foo", "bar", "baz"]` to `"foo, bar and baz"`
`["foo", "bar", "baz", "42"]` to `"foo, bar, baz and 42"`
- filter
- lists
- filters
- humanize
This is just a very short (and mostly useless on it's own) example of how the built in slugify filter can be used in a Python script to generate slugs. It was pulled from a script I've written to pull in items from Upcoming.org's API.
I post it because "sunturi" posted [Snippet #29](http://www.djangosnippets.org/snippets/29/), which duplicates the functionality of the built-in slugify filter. In the comments of that snippet, santuri (and others) seem to believe that template filters can only be used within templates. This is incorrect, and I think it's important people understand they can be used elsewhere.
sunturi's snippet does remove prepositions from values before slugifying them, so if you need that, his code will work work. But if all you need is slugification, the built-in slugify filter will work fine -- in a Python script, as well as in a template.
- template
- filter
- django
- slug
- built-in
When saving an edit to an object from a filtered list view you are, by default, returned to list view without any of your filters applied.
This solves that problem, keeping the filtered view in a session variable until you reach a point where the session key is deleted.
This solution doesn't require changes to template code...this is completely self contained within your own admin.py files.
The solution presented here is a revision of a previous patch, which has been modified for Django 1.4. The Django 1.3 version exists at:
http://djangosnippets.org/snippets/2531/
From chronosllc:
The advantage to our solution over the above linked solution is that under different use cases the user may or may not be redirected to the filtered list_view. For example, if you edit an object and click the save and continue button, then you would lose the filter when you finally finished editing the object and clicked save.
Added on here is a delete of the session key when users add objects, the reasoning we're going this route is we don't want to return users to filtered views when they just added a new object. Your mileage may vary and if so, it's easy enough to fit your own needs.