title: Associating a given django model with it's corresponding create/edit form
body: <p><strong>tl;dr</strong>: I'm looking for an easy way of associating a model's form with a given model, such that knowing only the model I can render the appropriate create/edit form.  I've developed a solution by storing the corresponding <code>ModelForm</code>'s name as a string attribute on the Model class, but being new to django, am curious if this is the preferred solution.</p>
  
  <hr>
  
  <p>I'm working on django task/project management site which will store tasks for a number of product groups. Navigating to <code>mysite/&lt;ProductGroup&gt;/create_task.html</code> should direct the user to a form for creating a task/project within that product group. By default, this will allow editing of a base <code>Task</code> model instance using a simple <code>ModelForm</code>.  However, for specific product groups I'd like to have the option of subclassing the <code>Task</code> model (example <code>SalesTask</code>) and displaying a <code>ModeForm</code> specific for that subclass (eg <code>SalesTaskForm</code>).  </p>
  
  <p>My current solution is to store the task-object-type as a contentype in the <code>ProductGroup</code> model, eg:</p>
  
  <pre><code>class ProductGroup(models.Model):
      task_type = models.ForeignKey(ContentType)
      ...
      &lt;define other fields here&gt;
  </code></pre>
  
  <p>Then define a base Task model with a special string attribute giving the corresponding <code>ModelForm</code> to use when rendering, eg:</p>
  
  <pre><code>&lt;models.py&gt;
  class Task(models.Model):
      product_group = models.ForeignKey(ProductGroup)
      ...
      &lt;define task fields common to all Task subclasses&gt;
      ...
      # Associate model with a form (regular python class attribute, 
      # not a django field)
      form = 'TaskForm'
  
  &lt;forms.py&gt;
  class TaskForm(ModelForm):
      class Meta:
          model = Task
  
  *Note that it would be slightly more convenient if I could set Task.form equal 
  to the actual TaskForm(ModelForm) class rather than a string, but I couldn't 
  get around the circular imports when trying this route (models.py `Task` 
  would need to import `Taskorm` from forms.py, which itself needs to import 
  `Task`).*
  </code></pre>
  
  <p>This setup allows me to easily extend the Task model for a given product group by simply subclassing <code>Task</code> and <code>TaskForm</code>, overriding the <code>Task.form</code> attribute on the model subclass definition (eg <code>SalesTask.form = 'SalesTaskForm'</code>) and then set the task_type foreign key for the sales instance of <code>ProductGroup</code>.</p>
  
  <p>The resulting <code>create_task</code> view function can then intelligently render the appropriate form for a given product group:</p>
  
  <pre><code>&lt;views.py&gt;
  ...
  import mysite.forms as taskforms
  ...
  def create_task(request, name):
      try:
          product_group = ProductGroup.object.get(product_group_iexact=name)
      except ProductGroup.DoesNotExist:
          raise Http404
  if request.method == 'POST':
      task_model = product_group.item_type.model_class()
      try:
          form = taskforms.__getattribute__(task_model.form)
      except AttributeError:
          raise Http404
  
      if form.is_valid():
          # Process form
      ...
  </code></pre>
  
  <p>This seems to work and I'm not unhappy with the solution, but it seems like a common need to associate a form with a given model and--being relatively new to django--I'm wondering if there's a built-in or more eloquent method of dealing with this?</p>
  
  <p>Thanks in advance.</p>