
Good day!
This topic is a continuation of the translation of the
Django documentation , to be exact - the section on
models .
')
Translation Django Documentation: Models. Part 1_____ Relationship between models
_______ Many-to-one ratio
_______ Many-to-many relationship
_______ Additional fields for many-to-many
_______ One-to-one ratio
_____ Models and Files
_____ Restrictions on field names
_____ Own field typesTranslation Django Documentation: Models. Part 3Translation Django Documentation: Models. Part 4 (Last)Relationships between models
Obviously, the main advantage of relational databases is the ability to define relationships between tables. Django provides options for defining the three most common types of relationships: many-to-one, many-to-many, and one-to-one.
Many-to-one relationshipForeignKey is used to define this kind of relationship. Its use is no different from using other types of fields: just add the corresponding attribute to your model.
When creating a field using the
ForeignKey , the method of the same name should be passed one positional argument: the class to which your model will refer.
For example, if a car (
Car ) has a manufacturer (
Manufacturer ) (a manufacturer creates a large number of machines, however each machine has only one manufacturer), the following definition is used:
Copy Source | Copy HTML<br/> class Manufacturer (models.Model):<br/> # ... <br/> <br/> class Car (models.Model):<br/> manufacturer = models.ForeignKey( Manufacturer )<br/> # ... <br/>
You can also create
recursive relationships (an object with a many-to-one relationship that refers to itself) and
relationships with a model that is not yet defined ; more detail
here .
As a field name of type
ForeignKey (
manufacturer in the example above), we suggest using the name of the model referenced by your class in lower case. This is an optional requirement and you can name the field as you like. For example:
Copy Source | Copy HTML<br/> class Car (models.Model):<br/> company_that_makes_it = models.ForeignKey(Manufacturer)<br/> # ... <br/>

A more detailed example you can find here is a
many-to-one relationship: an exampleFields of type
ForeignKey can also have a number of additional arguments that are considered in the
description of the fields of models . These optional parameters allow you to more accurately determine the work relationship.
Many attitude to manyTo determine this type of relationship,
ManyToManyField is used. Its use is no different from using other types of fields: just add the corresponding attribute to your model.
When creating a field using
ManyToManyField , one positional argument should be passed to the method of the same name: the class to which your model will refer.
For example, if a pizza (
Pizza ) has a
topping (one pizza can have many toppings, which in turn can be contained in many pizzas), you can imagine it this way:
Copy Source | Copy HTML<br/> class Topping (models.Model):<br/> # ... <br/> <br/> class Pizza (models.Model):<br/> # ... <br/> toppings = models.ManyToManyField( Topping ) <br/>
As with the
ForeignKey , you can create
recursive relationships (an object with a many-to-one relationship that refers to itself) and
relationships with a model that is not yet defined ; more detail
here .
As a field name of the
ManyToManyField type (
toppings in the example above), we suggest using a plural noun that describes many related objects.
It does not matter which model has an attribute of the
ManyToManyField type, the main thing is that it should be specified only in one of them.
As a rule, a field of type
ManyToManyField is defined in the object, which will later change in the administrator interface if you use the built-in Django admin panel (sorry, slang or tautology). In the example above, the
toppings are on pizza (
Pizza ), because it’s more usual for us to imagine pizza having different toppings than the stuffing contained on many pizzas. If you describe the model as shown above, the
Pizza form will allow users to select toppings.

A more detailed example you can find here is a
many-to-many relationship: an exampleFields of the
ManyToManyField type may also have a number of additional arguments that are considered in the
description of the fields of the models . These optional parameters allow you to more accurately determine the work relationship.
Additional fields for many-to-manyAdded in Django version 1.0 : please read the release notes .
As long as you are dealing with many-to-many trivial relationships, such as combining and matching pizzas and toppings, all you need is a standard type
ManyToManyField . However, sometimes you may need to associate data using a relationship between two models.
For example, consider the case when an application tracks groups in which some musicians took part. The relationship between the musician and the groups he or she is a member of will be many-to-many, so you can use
ManyToManyField to present it . However, you may also be interested in a large number of details, such as the date of joining the group or the reason why the musician left it.
For these situations, Django provides you with the ability to define a separate (intermediate) model that will be used to manage many-to-many relationships. You can create additional fields in the intermediate model. The intermediate model interacts with the
ManyToManyField using the through argument, which acts as an intermediary. For our musical (:)) example, the code will look like this:
Copy Source | Copy HTML<br/> class Person (models.Model):<br/> name = models.CharField(max_length= 128 )<br/> <br/> def __unicode__ (self):<br/> return self .name<br/> <br/> class Group (models.Model):<br/> name = models.CharField(max_length= 128 )<br/> members = models.ManyToManyField( Person , through= 'Membership' )<br/> <br/> def __unicode__ (self):<br/> return self .name<br/> <br/> class Membership (models.Model):<br/> person = models.ForeignKey( Person )<br/> group = models.ForeignKey( Group )<br/> date_joined = models.DateField()<br/> invite_reason = models.CharField(max_length= 64 ) <br/>
When creating an intermediate model, you explicitly specify foreign keys for models that are involved in a many-to-many type relationship. This is a clear declaration that determines how objects interact.
There are several limitations regarding intermediate models:
- Your intermediate model must contain one and only one foreign key to the target model (in our example, it is Person ), otherwise a validation error will be generated.
- Your intermediate model must contain one and only one foreign key to the original model (in our example, this is Group ), otherwise a validation error will be generated.
- The only exception is a model that relates to many-to-many with itself and refers to itself through an intermediate model. In this case, it is allowed to use two foreign keys to the same model, but they will be considered as two different parts in many-to-many relationships.
- To define a model that refers to itself using an intermediate model, you must use symmetrical = False (for more information, see the model fields ).
Now that you have set up ManyToManyField to interact with your intermediate model, you can start creating several many-to-many relationships. This is done by creating instances of your intermediate model:
Copy Source | Copy HTML<br/>>>> ringo = Person.objects.create(name= "Ringo Starr" )<br/>>>> paul = Person.objects.create(name= "Paul McCartney" )<br/>>>> beatles = Group.objects.create(name= "The Beatles" )<br/>>>> m1 = Membership(person=ringo, group=beatles,<br/>... date_joined=date( 1962 , 8 , 16 ),<br/>... invite_reason= "Needed a new drummer." )<br/>>>> m1.save()<br/>>>> beatles.members. all ()<br/>[<Person: Ringo Starr>]<br/>>>> ringo.group_set. all ()<br/>[<Group: The Beatles>]<br/>>>> m2 = Membership.objects.create(person=paul, group=beatles,<br/>... date_joined=date( 1960 , 8 , 1 ),<br/>... invite_reason= "Wanted to form a band." )<br/>>>> beatles.members. all ()<br/>[<Person: Ringo Starr>, <Person: Paul McCartney>] <br/>
Not very similar to regular fields: you cannot use the add and create methods, as well as the assignment operation (for example, beatles.members = [...] ) to define relationships:
Copy Source | Copy HTML<br/> # THIS WILL NOT WORK <br/>>>> beatles.members.add(john)<br/> # NEITHER WILL THIS <br/>>>> beatles.members.create(name= "George Harrison" )<br/> # AND NEITHER WILL THIS <br/>>>> beatles.members = [john, paul, ringo, george] <br/>
Why? You cannot simply create a relationship between Person and Group , so you must specify all the details of the relationship required by the intermediate Membership model. Simple methods add , create, and assignment do not provide the ability to determine additional details. Therefore, they are disabled in many-to-many relationships using the intermediate model. The only way to create this type of relationship is to create instances of the intermediate model.
The remove method is disabled for the same reasons. However, you can use the clear () method to remove all of the many-to-many relationships of an instance relationship:
Copy Source | Copy HTML<br/> # Beatles have broken up <br/>>>> beatles.members.clear() <br/>
So you created many-to-many relationships by creating instances of the intermediate model, you can now make queries. As well as in the case of a normal variant of relations, you can create queries using the attributes of the model:
Copy Source | Copy HTML<br/> # Find all the groups with a member whose name starts with 'Paul' <br/>>>> Group.objects. filter (members__name__startswith= 'Paul' )<br/>[<Group: The Beatles>] <br/>
Since you are using an intermediate model, you can also create queries using the attributes of the mediation model:
Copy Source | Copy HTML<br/> # Find all the members of the Beatles that joined after 1 Jan 1961 <br/>>>> Person.objects. filter (<br/>... group__name= 'The Beatles' ,<br/>... membership__date_joined__gt=date( 1961 , 1 , 1 ))<br/>[<Person: Ringo Starr] <br/>
One-to-one relationship
OneToOneField is used to determine this kind of relationship. Its use is no different from using other types of fields: just add the corresponding attribute to your model.
This kind of relationship is most useful in the case when one of the objects related by a relationship somehow expands or complements the other.
When creating a field using OneToOneField , one positional argument should be passed to the method with the same name: the class to which your model will refer.
For example, if you decide to create a database "Places", you are likely to add to it completely standard things, such as address, telephone, and so on. If you want to create a new database of restaurants that are located in places from the first database, instead of repeating and duplicating information in the fields of the Restaurant model, you can establish a one-to-one relationship between Restaurant and Place using OneToOneField (because is, in fact, a place; to cope with this task you will have to use inheritance , which implicitly includes the kind of one-to-one relationship).
As with the ForeignKey , you can create recursive relationships and relationships with a model that is not yet defined ; more detail here .

A more detailed example you can find here is a one-to-one relationship: an example
Added in Django version 1.0 : please read the release notes .
Fields of type OneToOneField accept one optional argument, which is considered in the description of the fields of the models .
Previously, the OneToOneField classes automatically became the primary keys of the model. This is no longer the case (although the ability to install primary_key manually remains). Thus, it is now possible to have several OneToOneField type fields in one model.
Models and files
It is quite possible to link two models from different applications. To do this, you should import the required model into the upper part of our model, and then simply refer to another class, if necessary. For example:
Copy Source | Copy HTML<br/> from mysite.geography.models import ZipCode<br/> <br/> class Restaurant (models.Model):<br/> # ... <br/> zip_code = models.ForeignKey(ZipCode) <br/>
Restrictions on field names
Django sets two restrictions on field names:- The field name cannot be a reserved Python word, otherwise it will cause a syntax error. For example:
Copy Source | Copy HTML<br/> class Example (models.Model):<br/> pass = models.IntegerField() # 'pass' is a reserved word! <br/>
- A field name cannot contain more than one underscore character in a row. This is a consequence of the query search system in Django. For example:
Copy Source | Copy HTML<br/> class Example (models.Model):<br/> foo__bar = models.IntegerField() # 'foo__bar' has two underscores! <br/>
These restrictions can be circumvented because your fields do not have to match the name of the column in the database (see db_column option ).
SQL reserved words such as join , where, or select can be used as field names, due to the fact that Django “leaves” all columns and columns of the database on every SQL query. Database mechanisms use reference syntax.
Own field types
Added in Django version 1.0 : please read the release notes .
If none of the existing field types can be used to achieve your goals, or if you want to take advantage of one of the less common column types, you can create your own field class. Full details on creating fields are provided in the section on writing your own field types .
Today everything :) to be continued
I will be glad to hear any suggestions, questions and comments.
Translation Django Documentation: Models. Part 1
Translation Django Documentation: Models. Part 3
Translation Django Documentation: Models. Part 4 (Last)