Snippet List
Provides an efficient means of looking up multiple related model instances for a range of objects by pre-filling the cache attribute used by `SingleRelatedObjectDescriptor` with either complete model instances or a dict containing only specified fields, looking up all required data with a single query.
Example usage:
C:\django_projects\soclone>django-admin.py shell
>>> from soclone.models import Question
>>> from soclone.views import populate_fk_caches
>>> from django.db import connection
>>> from django.contrib.auth.models import User
>>> q = Question.objects.get(id=1)
>>> a = list(q.answers.all())
>>> connection.queries = []
>>> populate_fk_caches(User, (
... ((q,), ('author', 'last_edited_by', 'closed_by')),
... (a, ('author', 'last_edited_by')),
... ),
... fields=('username', 'gravatar', 'reputation', 'gold', 'silver',
... 'bronze'))
>>> connection.queries
[{'time': '0.000', 'sql': u'SELECT "auth_user"."id", "auth_user"."username", "au
th_user"."gravatar", "auth_user"."reputation", "auth_user"."gold", "auth_user"."
silver", "auth_user"."bronze" FROM "auth_user" WHERE "auth_user"."id" IN (1, 2)'
}]
A widget for selecting from a list of `Model` instances using `MultipleChoiceField` which renders a table row for each choice, consisting of a column for a checkbox followed by a column for each item specified in `item_attrs`, which must specify attributes of the objects passed as choices.
- forms
- table
- widget
- selectmultiple
Based on the UPDATE query section of `Model.save()`, this is another means of limiting the fields which are used in an UPDATE statement and bypassing the check for object existence which is made when you use `Model.save()`.
Just make whatever changes you want to your model instance and call `update`, passing your instance and the names of any fields to be updated.
Usage example:
import datetime
from forum.models import Topic
from forum.utils.models import update
topic = Topic.objects.get(pk=1)
topic.post_count += 1
topic.last_post_at = datetime.datetime.now()
update(topic, 'post_count', 'last_post_at')
(Originally intended as a comment on [Snippet 479](/snippets/479/), but comments aren't working for me)
A URL field specifically for images, which can validate details about the filesize, dimensions and format of an image at a given URL, without having to read the entire image into memory.
Requires [Python Imaging Library](http://www.pythonware.com/library/pil/).
*4th October, 2008* - updated for 1.0 compatibility.
- image
- pil
- validation
- url
- form
- field
Have your forms descend from this BaseForm if you need to be able to render a valid form as hidden fields for re-submission, e.g. when showing a preview of something generated based on the form's contents.
Custom form example:
>>> from django import newforms as forms
>>> class MyForm(HiddenBaseForm, forms.Form):
... some_field = forms.CharField()
...
>>> f = MyForm({'some_field': 'test'})
>>> f.as_hidden()
u'<input type="hidden" name="some_field" value="test" id="id_some_field" />'
With `form_for_model`:
SomeForm = forms.form_for_model(MyModel, form=HiddenBaseForm)
- newforms
- form
- baseform
- hidden
Handles creation of `order_by` criteria based on GET parameters and provides context variables to be used when generating table header sort links which respect the current sort field and direction, reversing the direction when the same header is sorted by again.
Sample view:
from somewhere import SortHeaders
from django.contrib.auth.models import User
from django.shortcuts import render_to_response
LIST_HEADERS = (
('Username', 'username'),
('First Name', 'first_name'),
('Last Name', 'last_name'),
('Email', None),
)
def user_list(request):
sort_headers = SortHeaders(request, LIST_HEADERS)
users = User.objects.order_by(sort_headers.get_order_by())
return render_to_response('users/user_list.html', {
'users': users,
'headers': list(sort_headers.headers()),
})
Sample template:
{% load my_tags %}
<table cellspacing="0">
<thead>
<tr>
{% table_header headers %}
</tr>
</thead>
<tbody>
{% for user in users %}<tr class="{% cycle odd,even %}">
<td><a href="{{ user.get_absolute_url|escape }}">{{ user.username|escape }}</a></td>
<td>{{ user.first_name|escape }}</td>
<td>{{ user.last_name|escape }}</td>
<td>{{ user.email|escape }}</td>
</tr>
{% endfor %}
</tbody>
</table>
Sample inclusion tag:
from django import template
def table_header(context, headers):
return {
'headers': headers,
}
register = template.Library()
register.inclusion_tag('table_header.html', takes_context=True)(table_header)
Sample inclusion tag template:
{% for header in headers %}<th{{ header.class_attr }}>
{% if header.sortable %}<a href="{{ header.url|escape }}">{% endif %}
{{ header.text }}
{% if header.sortable %}</a>{% endif %}
</th>{% endfor %}
I often find something like this lurking at the end of my base templates - it'll show you which queries were run while generating the current page, but they'll start out hidden so as not to be a pain.
Of course, before this works, you'll need to satisfy all the criteria for getting debug information in your template context:
1. Have `'django.core.context_processors.debug'` in your `TEMPLATE_CONTEXT_PROCESSORS` setting (it was there in the default settings, last time I checked).
2. Have your current IP in your `INTERNAL_IPS` setting.
3. Use [RequestContext](http://www.djangoproject.com/documentation/templates_python/#subclassing-context-requestcontext) when rendering the current template (if you're using a generic view, you're already using `RequestContext`).
Piggybacks on the pagination-related template context variables provided by the `object_list` generic view, adding extra context variables for use in displaying links for a given number of pages adjacent to the current page and determining if the first and last pages are included in the displayed links.
Also makes it easy to implement consistent paging all over your site by implementing your pagination controls in a single place - paginator.html.
Optionally accepts a single argument to specify the number of page links adjacent to the current page to be displayed.
Usage:
`{% paginator %}`
`{% paginator 5 %}`
insin has posted 9 snippets.