This is an improvement on [snippet 984](http://www.djangosnippets.org/snippets/984/). Read it's description and [this blog post](http://zerokspot.com/weblog/2008/08/13/genericforeignkeys-with-less-queries/) for good explanations of the problem this solves.
Unlike snippet 984, this version is able to handle multiple generic foreign keys, generic foreign keys with nonstandard ct_field and fk_field names, and avoids unnecessary lookups to the ContentType table.
To use, just assign an instance of GFKManager as the objects attribute of a model that has generic foreign keys. Then:
MyModelWithGFKs.objects.filter(...).fetch_generic_relations()
The generic related items will be bulk-fetched to minimize the number of queries.
Here's an example of writing generic views in an object-oriented style, which allows for very fine-grained customization via subclassing. The snippet includes generic create and update views which are backwards compatible with Django's versions.
To use one of these generic views, it should be wrapped in a function that creates a new instance of the view object and calls it:
def create_object(request, *args, **kwargs):
return CreateObjectView()(request, *args, **kwargs)
If an instance of one of these views is placed directly in the URLconf without such a wrapper, it will not be thread-safe.
This is a simple manager that offers one additional method called `relate`, which fetches generic foreign keys (as referenced by `content_type` and `object_id` fields) without requiring one additional query for each contained element.
Basically, when working with generic foreign keys (and esp. in the usecase of having something like a tumblelog where you use an additional model just to have a single sorting point of multiple other models), don't do something like `result = StreamItem.objects.select_related()` but just fetch the content type with `result = StreamItem.objects.select_related('content_type')`, otherwise you will end up with first one query for the list of StreamItems but then also with one additional query for each item contained in this resultset.
When you now combine the latter call with `result = StreamItem.gfkmanager.relate(result)`, you will just get the one query for the item list + one query for each content type contained in this list (if the models have already been cached).
For further details, please read [this post](http://zerokspot.com/weblog/2008/08/13/genericforeignkeys-with-less-queries/) on my blog.
This is a ModelForms-based rewrite of the create_object and update_object generic views, with a few added features. The views now accept a "form_class" argument optionally in place of the "model" argument, so you can create and tweak your own ModelForm to pass in. They also accept a "pre_save" callback that can make any additional changes to the created or updated instance (based on request.user, for instance) before it is saved to the DB.
Usage: just save the code in a file anywhere on the PythonPath and use the create_object and update_object functions as views in your urls.py.
This is an update to [snippet 765](http://www.djangosnippets.org/snippets/765/) as I was having trouble getting it to work on branches/newforms-admin @ r7771.
There are just a few minor changes to the previous snippet, all simple stuff. I went ahead an added can_delete and can_order options that the previous snippet didn't include.
[More details in blog post](http://paltman.com/2008/06/29/edit-inline-support-for-generic-relations/).
A simple InlineModelAdmin class that enables you to edit models that are bound by the instance via a generic foreign key (`content_type`, `object_id` pair)
Use like:
class PlacementInlineOptions( generic.GenericTabularInline ):
model = Placement
extra = 2
ct_field_name = 'target_ct'
id_field_name = 'target_id'
Can be also found at #4667
Use this function to merge model objects (i.e. Users, Organizations, Polls, Etc.) and migrate all of the related fields from the alias objects the primary object.
Usage:
from django.contrib.auth.models import User
primary_user = User.objects.get(email='[email protected]')
duplicate_user = User.objects.get(email='[email protected]')
merge_model_objects(primary_user, duplicate_user)
This a small but very handy view that gives you a convenient direct access to your templates.
Now suppose you saved the snippet under `misc.py`, it's critical to add this snippet (or a similar one, once you get the idea) to your `urls.py`:
if settings.DEBUG:
# Direct Templates
urlpatterns += patterns('misc',
(r'^template/(?P<path>.*)$', 'direct_to_template', {'template': '%(path)s'}),
)
Now you are able to access any of your templates, in different directories by specifying their path after `template/`. e.g., http://example.com/template/news/index.html
Of course you can change it as you want, you can also add other values to the dict argument, the only required key is `'template'`. The whole dict is made available in the template as a context.
All GET parameters are made available in the template too. So `http://example.com/template/news/index.html?title=Testing Title` will make the `{{ title }}` var available in your template. So you can substitute basic variables quickly.
This is was inspired by [django.views.generic.simple.direct_to_template](http://www.djangoproject.com/documentation/generic_views/#django-views-generic-simple-direct-to-template)
In this type of model you are allowed to define a model with a generic type.
For instance, a location can be an address, GPS coordinates, an intersection and many others types. Using a many to many field, models can have multiple locations without worrying about the type of location referencing. New locations types can be added without changing the references in other models.
This code is also used in Django's built in ContentTypes app.