Django

Code

Ticket #6095: docs.2.diff

File docs.2.diff, 3.8 kB (added by floguy, 11 months 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

    old new  
    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