Ticket #6095: docs.diff

File docs.diff, 3.5 KB (added by floguy, 13 years ago)

Added some (fairly extensive) documentation for this ticket. Please review it to make sure it's up to snuff. I'm not as good of a writer as I am a coder :)

  • docs/model-api.txt

    975975                             name based upon the names of the two tables being joined.
    977977    =======================  ============================================================
     979Many-to-many relationships with an intermediary model
     982Sometimes many-to-many relationships require a bit more definition than a
     983standard ``ManyToManyField`` will allow.  For example, suppose that ``Topping``
     984object was pepperoni, and that you wanted to keep track of how many pepperoni
     985there were on each pizza.  In that case, Django allows for the specification of
     986an intermediary model -- Here's how that might look::
     988    class Topping(models.Model):
     989        # ...
     991    class Pizza(models.Model):
     992        # ...
     993        toppings = models.ManyToManyField(Topping, through='PizzaTopping')
     995    class PizzaTopping(models.Model):
     996        pizza = models.ForeignKey(Pizza)
     997        topping = models.ForeignKey(Topping)
     998        num_toppings = models.IntegerField(default=1)
     1000There are several things at play in this example.  The first thing to note is
     1001that a new model has been created named ``PizzaTopping`` (in your own
     1002applications, it can be named anything.  It need not be a concatenation of the
     1003two related model names) which has two ``ForeignKey`` relationships:: one to
     1004``Pizza``, and another to ``Topping``.
     1006The third field on our new ``PizzaTopping`` model is num_toppings, an
     1007``IntegerField``.  This will be used to store information about how many of
     1008each topping each pizza has.
     1010**NOTE:** Any extra fields on an intermediary model must either be nullable
     1011(``null``=True), or have a default value.
     1013To complete this intermediary many-to-many definition, it is necessary to link
     1014the intermediary model with the ``ManyToManyField``.  Doing so requires the use
     1015of the ``through`` property on the ``ManyToManyField``.  This must be a string
     1016representation of the intermediary model--in this case, ``PizzaTopping``.
     1018If you would like to specify a database table for the intermediary
     1019relationship, setting the db_table property on a ``ManyToManyField`` will no
     1020longer work correctly.  Instead, set the db_table property on the intermediary
     1021model's inner ``Meta`` class.
     1023Now that you've got your intermediary model set up and you have it attached as
     1024a ``ManyToManyField`` to Pizza, you can access the related data the same way as
     1025normal.  ``Pizza`` model instances will now have access to related toppings
     1026through the ``toppings`` attribute, and ``Topping`` model instances will now
     1027have access to related pizzas through the ``pizza_set`` attribute.
     1029The additional information (in this case, num_toppings) is available by
     1030accessing the intermediary model just like you would access any other model.
     1034    my_pizza = Pizza.objects.get(id=1)
     1035    pepperoni = Topping.objects.get(id=1)
     1036    pizza_topping = PizzaTopping.objects.get(pizza=my_pizza, topping=pepperoni)
     1037    pizza_topping.num_toppings = 25
     1038    pizza_topping.save()
     1040For more examples on how to work with ``ManyToManyField``s, `see the tests`_.
     1042.. _see the tests: http://code.djangoproject.com/browser/django/trunk/tests/modeltests/m2m_manual/models.py
    9791044One-to-one relationships
Back to Top