Ticket #6095: docs.2.diff

File docs.2.diff, 3.8 KB (added by floguy, 7 years ago)

Updated the documentation to match the newest patch. Also tried to clarify some of the main points so that they were easier to understand.

  • docs/model-api.txt

     
    976976
    977977    =======================  ============================================================
    978978
     979Many-to-many relationships with an intermediary model
     980~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     981
     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 via the usage of a ``through`` keyword argument to a
     987``ManyToManyField`` -- Here's how that might look::
     988
     989    class Topping(models.Model):
     990        # ...
     991
     992    class Pizza(models.Model):
     993        # ...
     994        toppings = models.ManyToManyField(Topping, through='PizzaTopping')
     995   
     996    class PizzaTopping(models.Model):
     997        pizza = models.ForeignKey(Pizza)
     998        topping = models.ForeignKey(Topping)
     999        num_toppings = models.IntegerField()
     1000
     1001There are several elements at play in this example.  The first thing to note is
     1002that a new model has been created named ``PizzaTopping`` (in your own
     1003applications, it can be named anything.  It need not be a concatenation of the
     1004two related model names) which has two ``ForeignKey`` relationships: one to
     1005``Pizza``, and another to ``Topping``.
     1006
     1007The third field on our new ``PizzaTopping`` model is num_toppings, which is an
     1008``IntegerField``.  This will be used to store information about how many of
     1009each topping, each pizza has.
     1010
     1011To complete this intermediary many-to-many definition, it is necessary to link
     1012the intermediary model with the ``ManyToManyField``.  Doing so requires the use
     1013of the ``through`` property on the ``ManyToManyField``.  This must be a string
     1014representation of the intermediary model -- in this case, ``PizzaTopping``.
     1015
     1016If you would like to specify a database table for the intermediary
     1017relationship, setting the db_table property on a ``ManyToManyField`` will no
     1018longer work correctly.  Instead, set the db_table property on the intermediary
     1019model's inner ``Meta`` class if a different database table name is needed.
     1020
     1021Now that you've got your intermediary model set up and you have it attached as
     1022a ``ManyToManyField`` to Pizza, you can access the related data the same way as
     1023with a normal ``ManyToManyField``.  ``Pizza`` model instances will now have
     1024access to related toppings through the ``toppings`` descriptor, and ``Topping``
     1025model instances will now have access to related pizzas through the
     1026``pizza_set`` descriptor.
     1027
     1028The additional information (in this case, num_toppings) is available by
     1029accessing the intermediary model just like you would access any other model.
     1030
     1031Example::
     1032   
     1033    my_pizza = Pizza.objects.get(pk=1)
     1034    pepperoni = Topping.objects.get(pk=1)
     1035    pizza_topping = PizzaTopping(pizza=my_pizza, topping=pepperoni, num_toppings=25)
     1036    pizza_topping.save()
     1037
     1038.. note::
     1039    As soon as an intermediary model is specified, the ``add`` and
     1040    ``remove`` methods become unavailable on the descriptors added by the
     1041    ``ManyToManyField``.  For example, something like
     1042    ``Pizza.toppings.add(pepperoni)`` will no longer work, as there is not
     1043    enough information given to fully create an intermediary model instance
     1044    (case in point: there's no information about ``num_toppings``--
     1045    a required field on ``PizzaTopping``).
     1046
     1047For more examples and ideas on how to work with intermediary models,
     1048`see the tests`_.
     1049
     1050.. _see the tests: http://code.djangoproject.com/browser/django/trunk/tests/modeltests/m2m_manual/models.py
     1051
    9791052One-to-one relationships
    9801053~~~~~~~~~~~~~~~~~~~~~~~~
    9811054
Back to Top