You can use this template loader if you want to use template specifically from one app. Useful mainly in overriding admin templates - just make your own `admin/change_form.html` and have it extend `admin:admin/change_form.html` withou creating any symlinking or copying django admin's templates to alternate location.
Part of the [ella project](http://www.ellaproject.cz/).
This is a template tag that works like `{% include %}`, but instead of loading a template from a file, it uses some text from the current context, and renders that as though it were itself a template. This means, amongst other things, that you can use template tags and filters in database fields.
For example, instead of:
`{{ flatpage.content }}`
you could use:
`{% render_as_template flatpage.content %}`
Then you can use template tags (such as `{% url showprofile user.id %}`) in flat pages, stored in the database.
The template is rendered with the current context.
Warning - only allow trusted users to edit content that gets rendered with this tag.
Formats float values with specified number of significant digits (defaults to 3).
Usage:
`{{value|sigdig}} # with 3 significant digits by default`
`{{value|sigdig:digits}}`
Examples:
`{{0.001432143|sigdig}}` renders as `0.00143`
`{{874321.4327184|sigdig}}` renders as `874000`
`{{874321.4327184|sigdig:5}}` renders as `874320`
Useful for scientific or engineering presentation.
This is heavily inspired by [http://code.google.com/p/smorgasbord/](http://code.google.com/p/smorgasbord/). But that couldn't reuse an existing jinja2 Environment, nor set filters on the Environment it created.
This code assumes that you have `env` declared previously in the file as your Jinja2 Environment instance.
In `settings.py`, you should set
KEEP_DJANGO_TEMPLATES = (
'/django/contrib/',
)
so that your Django admin still works. You can also set any other places that you do want to use Django templates there.
By enabling this backend:
AUTHENTICATION_BACKENDS = (
'path.to.my.backends.CaseInsensitiveModelBackend',
)
Your users will now be able to log in with their username, no matter whether the letters are upper- or lower-case.
This allows you to create an alphabetical filter for a list of objects; e.g. `Browse by title: A-G H-N O-Z`. See [this entry](http://developer.yahoo.com/ypatterns/pattern.php?pattern=alphafilterlinks) in Yahoo's design pattern library for more info.
NamePaginator works like Django's Paginator. You pass in a list of objects and how many you want per letter range ("page"). Then, it will dynamically generate the "pages" so that there are approximately `per_page` objects per page.
By dynamically generating the letter ranges, you avoid having too many objects in some letter ranges and too few in some. If your list is heavy on one end of the letter range, there will be more pages for that range.
It splits the pages on letter boundaries, so not all the pages will have exactly `per_page` objects. However, it will decide to overflow or underflow depending on which is closer to `per_page`.
**NamePaginator Arguments**:
`object_list`: A list, dictionary, QuerySet, or something similar.
`on`: If you specified a QuerySet, this is the field it will paginate on. In the example below, we're paginating a list of Contact objects, but the `Contact.email` string is what will be used in filtering.
`per_page`: How many items you want per page.
**Examples:**
>>> paginator = NamePaginator(Contacts.objects.all(), \
... on="email", per_page=10)
>>> paginator.num_pages
4
>>> paginator.pages
[A, B-R, S-T, U-Z]
>>> paginator.count
36
>>> page = paginator.page(2)
>>> page
'B-R'
>>> page.start_letter
'B'
>>> page.end_letter
'R'
>>> page.number
2
>>> page.count
8
In your view, you have something like:
contact_list = Contacts.objects.all()
paginator = NamePaginator(contact_list, \
on="first_name", per_page=25)
try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1
try:
page = paginator.page(page)
except (InvalidPage):
page = paginator.page(paginator.num_pages)
return render_to_response('list.html', {"page": page})
In your template, have something like:
{% for object in page.object_list %}
...
{% endfor %}
<div class="pagination">
Browse by title:
{% for p in page.paginator.pages %}
{% if p == page %}
<span class="selected">{{ page }}</span>
{% else %}
<a href="?page={{ page.number }}">
{{ page }}
</a>
{% endif %}
{% endfor %}
</div>
It currently only supports paginating on alphabets (not alphanumeric) and will throw an exception if any of the strings it is paginating on are blank. You can fix either of those shortcomings pretty easily, though.
A simple addition to the settings.py file of your project to allow you to easily specify entire network ranges as internal. This is especially useful in conjunction with other tools such as the [Django Debug Toolbar](http://github.com/robhudson/django-debug-toolbar/tree/master).
After you set this up, the following test should pass
test_str = """
>>> '192.168.1.5' in INTERNAL_IPS
True
>>> '192.168.3.5' in INTERNAL_IPS
FALSE
"""
Requirements
------------
* The [IPy module](http://software.inl.fr/trac/wiki/IPy)
Acknowledgements
----------------
Jeremy Dunck: The initial code for this idea is by Jeremy and in [Django ticket #3237](http://code.djangoproject.com/ticket/3237). I just changed the module and altered the use of the list superclass slightly. I mainly wanted to put the code here for safe keeping. Thanks Jeremy!
There are probably ways to improve the implementation, but this was something I came up with when I wanted to change the default size of all of my CharField admin fields. Now all I have to do in my ModelAdmin class is:
form = get_admin_form(model)
or subclass BaseAdminForm if I need extra validation or more widget customization for an individual admin form.