| | 979 | Many-to-many relationships with an intermediary model |
| | 980 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | 981 | |
| | 982 | Sometimes many-to-many relationships require a bit more definition than a |
| | 983 | standard ``ManyToManyField`` will allow. For example, suppose that ``Topping`` |
| | 984 | object was pepperoni, and that you wanted to keep track of how many pepperoni |
| | 985 | there were on each pizza. In that case, Django allows for the specification of |
| | 986 | an 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 | |
| | 1001 | There are several elements at play in this example. The first thing to note is |
| | 1002 | that a new model has been created named ``PizzaTopping`` (in your own |
| | 1003 | applications, it can be named anything. It need not be a concatenation of the |
| | 1004 | two related model names) which has two ``ForeignKey`` relationships: one to |
| | 1005 | ``Pizza``, and another to ``Topping``. |
| | 1006 | |
| | 1007 | The 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 |
| | 1009 | each topping, each pizza has. |
| | 1010 | |
| | 1011 | To complete this intermediary many-to-many definition, it is necessary to link |
| | 1012 | the intermediary model with the ``ManyToManyField``. Doing so requires the use |
| | 1013 | of the ``through`` property on the ``ManyToManyField``. This must be a string |
| | 1014 | representation of the intermediary model -- in this case, ``PizzaTopping``. |
| | 1015 | |
| | 1016 | If you would like to specify a database table for the intermediary |
| | 1017 | relationship, setting the db_table property on a ``ManyToManyField`` will no |
| | 1018 | longer work correctly. Instead, set the db_table property on the intermediary |
| | 1019 | model's inner ``Meta`` class if a different database table name is needed. |
| | 1020 | |
| | 1021 | Now that you've got your intermediary model set up and you have it attached as |
| | 1022 | a ``ManyToManyField`` to Pizza, you can access the related data the same way as |
| | 1023 | with a normal ``ManyToManyField``. ``Pizza`` model instances will now have |
| | 1024 | access to related toppings through the ``toppings`` descriptor, and ``Topping`` |
| | 1025 | model instances will now have access to related pizzas through the |
| | 1026 | ``pizza_set`` descriptor. |
| | 1027 | |
| | 1028 | The additional information (in this case, num_toppings) is available by |
| | 1029 | accessing the intermediary model just like you would access any other model. |
| | 1030 | |
| | 1031 | Example:: |
| | 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 | |
| | 1047 | For 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 | |