Django generic views let the developper to quickly write common pattern to create, update, delete and show objects. There is a common problem with the create / update generic view discussed on the django developpers mail list with solutions on the django wiki. Generic view create_object generates a HttpResponse from a model name. You can then write a basic template and use the form generated by the generic view.

A basic example starting with the model.py:

class Thing(models.Model):
    name = models.CharField(maxlength=100)

views.py (note you can directly write it in your urls.py file as in the django documentation):

from myapp.models import Thing
 
def create_thing(request):
    return django.views.generic.create_update.create_object(Thing, 
             template='create.html', post_save_redirect="..")

In the urls.py file:

(r'^creatething/', "myapp.views.create_thing")

In the template create.html:

<form method="post" action="">
  <p>
    <label for="id_name">Name:</label> {{ form.name }}
  </p>
  <input type="submit" />
</form>

And, that's all ! Now, we are going to update our models:

class Element(models.Model):
    name = models.CharField(maxlength=100)
 
class Thing(models.Model):
    element = models.ForeignKey(Element)
    name = models.CharField(maxlength=100)

The default behavior of the generic_view is to generate a form with a combobox to select the foreign element from a list. The problem here, if there is a lot of Element objects, django needs to get all data from the Element table and generate an enormous combobox. We are solving this problem by using the raw_id_admin option. Note: the problem go upstream to the generic view from the AutomaticManipulator.

Supposing we are creating Thing from an element_detail page.

(r'^(?P<elementname>\w+)/creatething/$', "myapp.views.create_thing")

Add the raw_id_admin option:

class Thing(models.Model):
    element = models.ForeignKey(Element, raw_id_admin=True)
    name = models.CharField(maxlength=100)

Modify the views.py

from myapp.models import Thing, Other
 
def create_thing(request, elementname):
    element = get_object_or_404(Element, name=elementname)
    return django.views.generic.create_update.create_object(Thing, 
        template='create.html', context={'element':element}, 
        post_save_redirect="..")

Modify the template:

<form method="post" action="">
  <input type="hidden" id="id_element" name="element" value="{{element.id}}" />
  <p>
    <label for="id_name">Name:</label> {{ form.name }}
  </p>
  <input type="submit" />
</form>

Ok, the performance problem for creating a new Thing is solved, but you need to find the Element before. How ?