Snippet List
Sometimes it is desirable to use values like the primary key when naming `FileField` and `ImageField` files, but such values are only available after saving the model instance. This abstract class implements a two-phase save in order to make this case easy. See the example in the docstring.
Another solution would be to write a `save()` that requires `upload_to` to be a callable that checks for `instance.pk`, then calls it again after saving. However, this would require more work from the developer for simple cases.
- imagefield
- filefield
- rename
- upload_to
This form subclass helps protect against cross-site request forgery by adding a hidden field named `csrf_token` to forms. The form must be initialized with the request as a keyword argument, both with and without POST data:
my_form = MySignedForm(request=request)
...
my_form = MySignedForm(request.POST, request=request)
Upon validation, a `PermissionDenied` exception will be raised if forgery is detected.
If any security details have been overlooked in this recipe, please leave a comment.
This management command discovers media files from all `INSTALLED_APPS` (or the apps you specify) and copies or links them to `MEDIA_ROOT`. Put this code in a file like so:
yourapp/management/commands/collectmedia.py
...and don't forget the necessary `__init__.py` files.
This command includes an interactive mode (`-i` or `--interactive`) and a dry run mode (`-n` or `--dry-run`) for previewing what will happen. See `manage.py help collectmedia` for more options.
If you add a lot of custom `ModelAdmin` methods to `list_display` like I do, you know it can require a lot of repetition. Notice how adding 'checkbox' to `list_display` requires typing the method name 4 times:
class ExampleAdmin(admin.ModelAdmin):
list_display = ['checkbox', '__str__']
def checkbox(self, object):
return '<input type="checkbox" value="%s"/>' % object.pk
checkbox.short_description = mark_safe('✓')
checkbox.allow_tags = True
Using this decorator, the name only needs to be typed once:
class ExampleAdmin(admin.ModelAdmin):
list_display = ['__str__']
@add(list_display, mark_safe('✓'), 0, allow_tags=True)
def checkbox(self, object):
return '<input type="checkbox" value="%s"/>' % object.pk
- admin
- modeladmin
- list_display
This template tag and suggested template allow greater control over rendering `<label>` tags for your newforms fields than using `field.label_tag`. I save the provided Python code in my app as `templatetags/forms.py` (although this name may conflict in the future).
The simplest usage:
{% label field %}
One use case is adding `class="required"` to the label tag for required fields instead of inserting markup elsewhere--this is done in the given example template.
Alternate label text and tag attributes can be passed to the inclusion tag:
{% label field "Alt. label" 'class=one,id=mylabel' %}
- templatetag
- newforms
- label
Use these tags and filter when you're rolling your own search results. This is intended to be a whole templatetags module. I keep it in my apps as `templatetags/search.py`. These should not be used to perform search queries, but rather render the results.
### Basics
There are three functions, each has both a tag *and* a filter of the same name. These functions accept, at a minimum, a body of text and a list of search terms:
* **searchexcerpt**: Truncate the text so that each search term is shown, surrounded by some number of words of context.
* **highlight**: Wrap all found search terms in an HTML span that can be styled to highlight the terms.
* **hits**: Count the occurrences of the search terms in the text.
The filters provide the most basic functionality as described above, while the tags offer more options as arguments, such as case sensitivity, whole word search, and saving the results to a context variable.
### Settings
Defaults for both the tags and filters can be changed with the following settings. Note that these settings are merely a convenience for the tags, which accept these as arguments, but are necessary for changing behavior of the filters.
* `SEARCH_CONTEXT_WORDS`: Number of words to show on the left and right of each search term. Default: 10
* `SEARCH_IGNORE_CASE`: False for case sensitive, True otherwise. Default: True
* `SEARCH_WORD_BOUNDARY`: Find whole words and not strings in the middle of words. Default: False
* `SEARCH_HIGHLIGHT_CLASS`: The class to give the HTML span element when wrapping highlighted search terms. Default: "highlight"
### Examples
Suppose you have a list `flatpages` resulting from a search query, and the search terms (split into a list) are in the context variable `terms`. This will show 5 words of context around each term and highlight matches in the title:
{% for page in flatpages %}
<h3>{{ page.title|highlight:terms }}</h3>
<p>
{% searchexcerpt terms 5 %}
{{ page.content|striptags }}
{% endsearchexcerpt %}
</p>
{% endfor %}
Add highlighting to the excerpt, and use a custom span class (the two flags are for case insensitivity and respecting word boundaries):
{% highlight 1 1 "match" %}
{% searchexcerpt terms 5 1 1 %}
{{ page.content|striptags }}
{% endsearchexcerpt %}
{% endhighlight %}
Show the number of hits in the body:
<h3>{{ page.title }}
(Hits: {{ page.content|striptags|hits:terms }})
</h3>
All tags support an `as name` suffix, in which case an object will be stored in the template context with the given name; output will be suppressed. This is more efficient when you want both the excerpt and the number of hits. The stored object depends on the tag:
* **searchexcerpt**: A dictionary with keys "original" (the text searched), "excerpt" (the summarized text with search terms), and "hits" (the number of hits in the text).
* **searchcontext**: A dictionary with keys "original", "highlighted", and "hits", with obvious values.
* **hits**: Just the number of hits, nothing special.
Getting both the hits and the excerpt with "as":
{% searchexcerpt terms 3 as content %}
{{ page.content|striptags }}
{% endsearchexcerpt %}
<p>Hits: {{ content.hits }}<br>{{ content.excerpt }}</p>
### More
For more examples see [Brian Beck's Text Adventure][announcement].
[announcement]: http://blog.brianbeck.com/post/29707610
- filter
- tag
- search
- templatetags
- context
- highlight
- excerpt
Sometimes it's nice to know if your visitors came from a search engine such as Google or Yahoo. I use this as a component in determining the popularity of blog articles for search keywords, so I know which articles to automatically feature or suggest. Maybe you'd like to use it to highlight the visitor's search terms on the page.
This isn't actually middleware in the sense that it defines any of the middleware interfaces. It's intended to be the base for a middleware method that you write, depending on what you want to happen when you detect that the visitor came from a search engine. In the example `process_view` method, I detect when the request is going to use the `object_detail` view and log the search query for that object in the database.
- middleware
- search-engine
- referrer
Ever since django.contrib.markup appeared I've added a `markup_lang` field to my models where I want to support multiple input formats. This filter lets you pass the filter name as a string (from your model field, for example) and it will call the appropriate filter. I use None when the text is HTML, in which case it will return as-is.
Example:
class Article(models.Model):
content = models.TextField(null=False, default="")
markup_lang = models.CharField(maxlength=20, blank=True)
a = Article(content="**Test!**", markup_lang='textile')
b = Article(content="<h1>Hello!</h1>")
And in a template:
{% for article in article_list %}
{{ article.content|render_markup:article.markup_lang }}
{% endfor %}
I prefer to use this slugification function rather than the one included with Django. It uses underscores instead of dashes for spaces, and allows dashes and periods to occur normally in the string. I decided on this when considering reasonable slugified titles such as...
object-relational_mapper_2.5
ten_reasons_web-2.0_rocks
django-trunk_0.99_updated
- filter
- slugs
- slug
- slugify
I know you're thinking, *what the heck could that title mean?*
I often find myself wanting to filter and order by the result of a COUNT(*) of a query using a method similar to the [entry_count example](http://www.djangoproject.com/documentation/db-api/#extra-select-none-where-none-params-none-tables-none). Writing this many times is tedious and hardcoding the table and column names made me cringe, I also wanted the counts to result from more complex queries.
This is a method you can add to your custom Manager to do this easily. It's not an ideal syntax, but it's good for the amount of code required.
Example: suppose we have some articles we want to filter and order by comments and visit logs to show the most popular...
class ArticleManager(models.Manager):
count_related = _count_related
class Article(models.Model):
pub_date = models.DateTimeField(auto_now_add=True)
objects = ArticleManager()
class Comment(models.Model):
article = models.ForeignKey(Article)
is_spam = models.BooleanField(default=False)
class Visit(models.Model):
article = models.ForeignKey(Article)
referrer = models.URLField(verify_exists=False)
search_query = models.CharField(maxlength=200)
Notice how the ArticleManager is given the `count_related` method. Now you can find the most popular like so...
Order by non-spam comments:
Article.objects.count_related(Comment.objects.filter(
is_spam=False)).order_by('-comment__count')
Order by incoming non-search-engine links:
Article.objects.count_related(Visit.objects.filter(
referrer__isnull=False, search_query__isnull=True),
'links').order_by('-links')
Order by total visits:
Article.objects.count_related(Visit).order_by('-visit__count')
Note: Doesn't work if `query` contains joins or for many-to-many relationships, but those could be made to work identically if there's demand.
- sql
- model
- db
- count
- manager
exogen has posted 10 snippets.