Django also defines a set of fields that represent relations.
A many-to-one relationship. Requires a positional argument: the class to which the model is related. To create a recursive relationship-an object that has a many-to-one relationship with itself-use models.ForeignKey('self')
.
If you need to create a relationship on a model that has not yet been defined, you can use the name of the model, rather than the model object itself:
from django.db import models class Car(models.Model): manufacturer = models.ForeignKey('Manufacturer') # ... class Manufacturer(models.Model): # ... pass
To refer to models defined in another application, you can explicitly specify a model with the full application label. For example, if the Manufacturer
model above is defined in another application called production
, you'd need to use:
class Car(models.Model): manufacturer = models.ForeignKey('production.Manufacturer')
This sort of reference can be useful when resolving circular import dependencies between two applications. A database index is automatically created on the ForeignKey
. You can disable this by setting db_index
to False
.
You may want to avoid the overhead of an index if you are creating a foreign key for consistency rather than joins, or if you will be creating an alternative index like a partial or multiple column index.
Behind the scenes, Django appends "_id"
to the field name to create its database column name. In the above example, the database table for the Car
model will have a manufacturer_id
column.
You can change this explicitly by specifying db_column
, however, your code should never have to deal with the database column name, unless you write custom SQL. You'll always deal with the field names of your model object.
ForeignKey
accepts an extra set of arguments-all optional-that define the details of how the relation works.
Sets a limit to the available choices for this field when this field is rendered using a ModelForm
or the admin (by default, all objects in the queryset are available to choose). Either a dictionary, a Q
object, or a callable returning a dictionary or Q
object can be used. For example:
staff_member = models.ForeignKey(User, limit_choices_to={'is_staff': True})
causes the corresponding field on the ModelForm
to list only Users
that have is_staff=True
. This may be helpful in the Django admin. The callable form can be helpful, for instance, when used in conjunction with the Python datetime
module to limit selections by date range. For example:
def limit_pub_date_choices(): return {'pub_date__lte': datetime.date.utcnow()} limit_choices_to = limit_pub_date_choices
If limit_choices_to
is or returns a Q object
, which is useful for complex queries, then it will only have an effect on the choices available in the admin when the field is not listed in raw_id_fields
in the ModelAdmin
for the model.
The name to use for the relation from the related object back to this one. It's also the default value for related_query_name
(the name to use for the reverse filter name from the target model). See the related objects documentation for a full explanation and example. Note that you must set this value when defining relations on abstract models; and when you do so some special syntax is available. If you'd prefer Django not to create a backwards relation, set related_name
to '+'
or end it with '+'
. For example, this will ensure that the User
model won't have a backwards relation to this model:
user = models.ForeignKey(User, related_name='+')
The name to use for the reverse filter name from the target model. Defaults to the value of related_name
if it is set, otherwise it defaults to the name of the model:
# Declare the ForeignKey with related_query_name class Tag(models.Model): article = models.ForeignKey(Article, related_name="tags", related_query_name="tag") name = models.CharField(max_length=255) # That's now the name of the reverse filter Article.objects.filter(tag__name="important")
The field on the related object that the relation is to. By default, Django uses the primary key of the related object.
Controls whether or not a constraint should be created in the database for this foreign key. The default is True
, and that's almost certainly what you want; setting this to False
can be very bad for data integrity. That said, here are some scenarios where you might want to do this:
If this is set to False
, accessing a related object that doesn't exist will raise its DoesNotExist
exception.
When an object referenced by a ForeignKey
is deleted, Django by default emulates the behavior of the SQL constraint ON DELETE CASCADE
and also deletes the object containing the ForeignKey
. This behavior can be overridden by specifying the on_delete
argument. For example, if you have a nullable ForeignKey
and you want it to be set null when the referenced object is deleted:
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)
The possible values for on_delete
are found in django.db.models
:
CASCADE
: Cascade deletes; the defaultPROTECT
: Prevent deletion of the referenced object by raising ProtectedError
, a subclass of django.db.IntegrityError
SET_NULL
: Set the ForeignKey
null; this is only possible if null
is True
SET_DEFAULT
: Set the ForeignKey
to its default value; a default for the ForeignKey
must be setControls the migration framework's reaction if this ForeignKey
is pointing at a swappable model. If it is True
-the default-then if the ForeignKey
is pointing at a model which matches the current value of settings.AUTH_USER_MODEL
(or another swappable model setting) the relationship will be stored in the migration using a reference to the setting, not to the model directly.
You only want to override this to be False
if you are sure your model should always point towards the swapped-in model-for example, if it is a profile model designed specifically for your custom user model. Setting it to False
does not mean you can reference a swappable model even if it is swapped out-False
just means that the migrations made with this ForeignKey
will always reference the exact model you specify (so it will fail hard if the user tries to run with a User model you don't support, for example). If in doubt, leave it to its default of True
.
A many-to-many relationship. Requires a positional argument: the class to which the model is related, which works exactly the same as it does for ForeignKey
, including recursive and lazy relationships. Related objects can be added, removed, or created with the field's RelatedManager
.
Behind the scenes, Django creates an intermediary join table to represent the many-to-many relationship. By default, this table name is generated using the name of the many-to-many field and the name of the table for the model that contains it.
Since some databases don't support table names above a certain length, these table names will be automatically truncated to 64 characters and a uniqueness hash will be used. This means you might see table names like author_books_9cdf4
; this is perfectly normal. You can manually provide the name of the join table using the db_table
option.
ManyToManyField
accepts an extra set of arguments-all optional-that control how the relationship functions.
Same as ForeignKey.limit_choices_to
. limit_choices_to
has no effect when used on a ManyToManyField
with a custom intermediate table specified using the through
parameter.
Only used in the definition of ManyToManyFields on self. Consider the following model:
from django.db import models class Person(models.Model): friends = models.ManyToManyField("self")
When Django processes this model, it identifies that it has a ManyToManyField
on itself, and as a result, it doesn't add a person_set
attribute to the Person
class. Instead, the ManyToManyField
is assumed to be symmetrical-that is, if I am your friend, then you are my friend.
If you do not want symmetry in many-to-many relationships with self
, set symmetrical
to False
. This will force Django to add the descriptor for the reverse relationship, allowing ManyToManyField
relationships to be non-symmetrical.
Django will automatically generate a table to manage many-to-many relationships. However, if you want to manually specify the intermediary table, you can use the through
option to specify the Django model that represents the intermediate table that you want to use.
The most common use for this option is when you want to associate extra data with a many-to-many relationship. If you don't specify an explicit through
model, there is still an implicit through
model class you can use to directly access the table created to hold the association. It has three fields:
id
: The primary key of the relation<containing_model>_id
: The id
of the model that declares the ManyToManyField
<other_model>_id
: The id
of the model that the ManyToManyField
points toThis class can be used to query associated records for a given model instance like a normal model.
Only used when a custom intermediary model is specified. Django will normally determine which fields of the intermediary model to use in order to establish a many-to-many relationship automatically.
The name of the table to create for storing the many-to-many data. If this is not provided, Django will assume a default name based upon the names of the table for the model defining the relationship and the name of the field itself.
Controls whether or not constraints should be created in the database for the foreign keys in the intermediary table. The default is True
, and that's almost certainly what you want; setting this to False
can be very bad for data integrity.
That said, here are some scenarios where you might want to do this:
It is an error to pass both db_constraint
and through
.
Controls the migration framework's reaction if this ManyToManyField
is pointing at a swappable model. If it is True
--the default-then if the ManyToManyField
is pointing at a model which matches the current value of settings.AUTH_USER_MODEL
(or another swappable model setting) the relationship will be stored in the migration using a reference to the setting, not to the model directly.
You only want to override this to be False
if you are sure your model should always point towards the swapped-in model-for example, if it is a profile model designed specifically for your custom user model. If in doubt, leave it to its default of True
. ManyToManyField
does not support validators
. null
has no effect since there is no way to require a relationship at the database level.
A one-to-one relationship. Conceptually, this is similar to a ForeignKey
with unique=True
, but the reverse side of the relation will directly return a single object. This is most useful as the primary key of a model which extends another model in some way; multi table inheritance is implemented by adding an implicit one-to-one relation from the child model to the parent model, for example.
One positional argument is required: the class to which the model will be related. This works exactly the same as it does for ForeignKey
, including all the options regarding recursive and lazy relationships. If you do not specify the related_name
argument for the OneToOneField
, Django will use the lower-case name of the current model as default value. With the following example:
from django.conf import settings from django.db import models class MySpecialUser(models.Model): user = models.OneToOneField(settings.AUTH_USER_MODEL) supervisor = models.OneToOneField(settings.AUTH_USER_MODEL, related_name='supervisor_of')
your resulting User
model will have the following attributes:
>>> user = User.objects.get(pk=1) >>> hasattr(user, 'myspecialuser') True >>> hasattr(user, 'supervisor_of') True
A DoesNotExist
exception is raised when accessing the reverse relationship if an entry in the related table doesn't exist. For example, if a user doesn't have a supervisor designated by MySpecialUser
:
>>> user.supervisor_of Traceback (most recent call last): ... DoesNotExist: User matching query does not exist.
Additionally, OneToOneField
accepts all of the extra arguments accepted by ForeignKey
, plus one extra argument:
When True
and used in a model which inherits from another concrete model, indicates that this field should be used as the link back to the parent class, rather than the extra OneToOneField
which would normally be implicitly created by subclassing. See One-to-one relationships in the next chapter for usage examples of OneToOneField
.