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
Inspired by http://www.djangosnippets.org/snippets/159/
This context processor provides a new variable {{ sqldebug }}, which can
be used as follows:
{% if sqldebug %}...{% endif %}
{% if sqldebug.enabled %}...{% endif %}
This checks settings.SQL_DEBUG and settings.DEBUG. Both need to be True,
otherwise the above will evaluate to False and sql debugging is considered
to be disabled.
{{ sqldebug }}
This prints basic information like total number of queries and total time.
{{ sqldebug.time }}, {{ sqldebug.queries.count }}
Both pieces of data can be accessed manually as well.
{{ sqldebug.queries }}
Lists all queries as LI elements.
{% for q in sqldebug.queries %}
<li>{{ q.time }}: {{ q }}</li>
{% endfor %}
Queries can be iterated as well. The query is automatically escaped and contains
<wbr> tags to improve display of long queries. You can use {{ q.sql }} to access
the unmodified, raw query string.
Here's a more complex example. It the snippet from:
http://www.djangosnippets.org/snippets/93/
adjusted for this context processor.
{% if sqldebug %}
<div id="debug">
<p>
{{ sqldebug.queries.count }} Quer{{ sqldebug.queries|pluralize:"y,ies" }}, {{ sqldebug.time }} seconds
{% ifnotequal sql_queries|length 0 %}
(<span style="cursor: pointer;" onclick="var s=document.getElementById('debugQueryTable').style;s.display=s.display=='none'?'':'none';this.innerHTML=this.innerHTML=='Show'?'Hide':'Show';">Show</span>)
{% endifnotequal %}
</p>
<table id="debugQueryTable" style="display: none;">
<col width="1"></col>
<col></col>
<col width="1"></col>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">SQL</th>
<th scope="col">Time</th>
</tr>
</thead>
<tbody>
{% for query in sqldebug.queries %}<tr class="{% cycle odd,even %}">
<td>{{ forloop.counter }}</td>
<td>{{ query }}</td>
<td>{{ query.time }}</td>
</tr>{% endfor %}
</tbody>
</table>
</div>
{% endif %}
- sql
- debug
- queries
- db
- database
- contextprocessor
This is an improvement of snippet 253 in that it supports database queries.
Implementing autocompletion for foreign keys takes a few steps:
1) Put the snippet above into <app>/widgets/autocomplete.py.
2) Create a view of your foreign key model (here: Donator) in <app>/donator/views.py:
from models import Donator
from widgets.autocomplete import autocomplete_response
def autocomplete(request):
return autocomplete_response(
request.REQUEST['text'], Donator, (
'line_1', 'line_2', 'line_3', 'line_4',
'line_5', 'line_6', 'line_7', 'line_8',
'^zip_code', 'location'
)
)
This view returns the autocompletion result by searching the fields in the tuple. Each word from the form field must appear at least in one database field.
3) Create a URLconf that points to this new view.
4) In the form where you need the autocompletion, define the widget of the foreign key field as an instance of AutoCompleteField:
from widget.autocomplete import AutoCompleteField
field.widget = AutoCompleteField(
url='/donator/autocomplete/'),
options={'minChars': 3}
)
The url parameter is the URL connected to the view in step 3), the options dict is passed on to the Ajax.Autocompleter JavaScript object.
Links:
* [Snippet 253](http://www.djangosnippets.org/snippets/253/)
* [Django and scriptaculous integration](http://wiki.script.aculo.us/scriptaculous/show/IntegrationWithDjango)
* [Ajax.Autocompleter](http://wiki.script.aculo.us/scriptaculous/show/Ajax.Autocompleter)
- ajax
- selection
- database
- autocomplete
- query
- foreign-key
- prototype
- scriptaculous
- protoculous
Every now and then you need to have items in your database which have a specific order. As SQL does not save rows in any order, you need to take care about this for yourself. No - actually, you don't need to anymore. You can just use this file - it is designed as kind-of plug-in for the Django ORM.
Usage is (due to use of meta-classes) quite simple. It is recommended to save this snippet into a separate file called `positional.py`. To use it, you only have to import `PositionalSortMixIn` from the `positional` module and inherit from it in your own, custom model (but *before* you inherit from `models.Model`, the order counts).
Usage example: Add this to your `models.py`
from positional import PositionalSortMixIn
class MyModel(PositionalSortMixIn, models.Model):
name = models.CharField(maxlength=200, unique=True)
Now you need to create the database tables: `PositionalSortMixIn` will automatically add a `postition` field to your model. In your views you can use it simply with `MyModel.objects.all().order_by('position')` and you get the objects sorted by their position. Of course you can move the objects down and up, by using `move_up()`, `move_down()` etc.
In case you feel you have seen this code somewhere - right, this snippet is a modified version of [snippet #245](/snippets/245/) which I made earlier. It is basically the same code but uses another approach to display the data in an ordered way. Instead of overriding the `Manager` it adds the `position` field to `Meta.ordering`. Of course, all of this is done automatically, you only need to use `YourItem.objects.all()` to get the items in an ordered way.
Update: Now you can call your custom managers `object` as long as the default manager (the one that is defined first) still returns all objects. This Mix-in absolutely needs to be able to access all elements saved.
In case you find any errors just write a comment, updated versions are published here from time to time as new bugs are found and fixed.
- db
- orm
- database
- plugin
- mixin