Relationship fields
ForeignKey, ManyToManyField and OneToOneField respectively define many-to-one, many-to-many and one-to-one relationships in the Model.
For example, a book is published by a publishing house, and a publishing house can publish many books. A book is written by multiple authors, and one author can write many books.
class Author(models.Model):
name=models.CharField(max_length=20)
class Publisher(models.Model):
name=models.CharField(max_length=20)
class Book(models.Model):
name=models.CharField(max_length=20)
pub=models.ForeignKey(Publisher)
authors=models.ManyToManyField(Author)
1. Associate an undefined Model
If you want to associate with an undefined Model To establish a model association, use the name of the model instead of the model object itself.
In the example, if Publisher and Author are defined after Book, they need to be written in the following form:
class Book(models.Model):
name=models.CharField(max_length=20)
pub=models.ForeignKey('Publisher ')
authors=models.ManyToManyField('Author')
2.Model is associated with itself
Model can have a many-to-one relationship with itself
class People(models.Model):
name=models.CharField(max_length =20)
leader=models.ForeignKey('self',blank=True,null=True)
Model can also have a many-to-many relationship with itself
class Person(models.Model):
friends = models. ManyToManyField("self")
By default, this association is symmetrical. If Person1 is a friend of Person2, then Person2 is also a friend of Person1
p1=Person()
p1.save()
p2= Person()
p2.save()
p3=Person()
p3.save()
p1.friends.add(p2,p3)
In the above case, if you want to find p3’s friends, you don’t need p3.person_set. all(), and just use p3.friends.all() directly
If you want to cancel this symmetrical relationship, set symmetrical to False
class Person2(models.Model):
friends=(models.ManyToManyField( "self",symmetrical=False)
To query the friends of p3, you need p3.person_set.all()
3. Reverse name related_name
Reverse name, used to point from the related field to the related field .
Note that when you define abstract models , you must explicitly specify the reverse name; only after you do this, some special syntax will work properly.
class Book(models.Model):
name=models.CharField(max_length=20)
pub=models.ForeignKey(Publisher,related_name='pub')
authors=models.ManyToManyField(Author,related_name='author' )
In this way, you can use related_name when using Publisher or Author to reversely query Book: publisher1.pub.all() or author1.author.all().
If you don’t want to set a reverse relationship, set related_name to '+' or end with '+'.
user = models.ForeignKey(User, related_name='+')
If there are multiple ManyToManyFields pointing to the same Model, it will be impossible to figure out which ManyToManyField field it is when querying FOO_set in reverse, and the reverse can be disabled Relationship:
users = models.ManyToManyField(User, related_name='u+')
referents = models.ManyToManyField(User, related_name='ref+')
4. Database RePResentation
Many-to-one: Django uses the ForeignKey field name + "_id" as the column name in the database. In the above example, BOOK There will be a publisher_id column in the data table corresponding to the model.
You can change the column name of this field by explicitly specifying db_column. However, there is no need to change the column name of the database unless you want to customize SQL.
Many-to-many: Django Create an intermediate table to represent the ManyToManyField relationship. By default, the name of the intermediate table is the combination of the two relational table names.
Since some databases have restrictions on the length of table names, the name of the intermediate table is automatically limited to 64 characters and contains a unique hash string. This
means that you might see table names like book_authors_9cdf4. You can manually specify the intermediate table name using the db_table option.
However, if you want to manually specify the intermediate table, you can use the through option to specify the model to use another model to manage the many-to-many relationship. And this model It is the model corresponding to the intermediate table:
class Person(models.Model):
name = models.CharField(max_length=128)
def __unicode__(self):
return self.name
class Group(models.Model ):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __unicode__(self):
return self.name
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(Person, through='Membership')
def __unicode__(self):
return self.name
class Membership (models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
date_joined = models.DateField()
invite_reason = models.CharField(max_length=64)
In this way, you can Record when a person joins the group.
To establish the relationship between Person and Group, you cannot use add, create, or remove, but need to use Membership.
>>> ringo = Person.objects.create(name="Ringo Starr")
>>> paul = Person.objects.create(name="Paul McCartney")
>> > beatles = Group.objects.create(name="The Beatles")
>>> m1 = Membership(person=ringo, group=beatles,
... date_joined=date(1962, 8, 16) ,
... invite_reason= "Needed a new drummer.")
>>> m1.save()
clear() can still be used
>>> beatles.members.clear ()
When a many-to-many relationship is associated with itself, the ForeignKey of the intermediate table can point to the same Model, but they must be regarded as both sides of the ManyToManyField, rather than being symmetrical, and symmetrical=False needs to be set.
5. Other parameters (Arguments)
5.1 ForeignKey accepts the following optional parameters, which define how the relationship operates.
ForeignKey.limit_choices_to
It is a dictionary containing filter conditions and corresponding values, used to filter associated objects in the Django management background. For example, using Python’s datetime Module, filter out associated objects that do not meet the filter conditions:
limit_choices_to = {'pub_date__lte': datetime.date.today}
Only associated objects whose pub_date is before the current date are allowed to be selected.
You can also use Q Objects instead of dictionaries, allowing for more complex filtering. When limit_choices_to is a Q object, it is not available if the foreign key field is placed in the raw_id_fields of ModelAdmin.
ForeignKey.to_field
Specifies which field in the related object the current relationship is associated with. By default, to_field points to the primary key of the related object.
ForeignKey.on_delete
When the object associated with the ForeignKey of a model object is deleted, by default this object will also be deleted cascading together.
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)
CASCADE: Default value, the model object will be deleted together with the ForeignKey associated object
SET_NULL: Change the model object's The ForeignKey field is set to null. Of course null needs to be set to True.
SET_DEFAULT: Set the ForeignKey field of the model object to the default value.
Protect: When deleting the ForeignKey associated object
, a ProtectedError will be generated so that the ForeignKey associated object will not be deleted.
SET(): Set the ForeignKey field of the model object to the value passed to SET().
def get_sentinel_user():
return User.objects.get_or_create(username='deleted')[0]
class MyModel(models.Model):
user = models.ForeignKey(User, on_delete=models.SET(get_sentinel_user ))
DO_NOTHING: Do nothing.
5.2 ManyToManyField accepts the following optional parameters, which define how the relationship operates.
ManyToManyField.limit_choices_to
has the same usage as ForeignKey.limit_choices_to.
limit_choices_to does not work for ManyToManyField with mediation table specified via the through parameter.
ManyToManyField.symmetrical
only works when defining a recursive many-to-many relationship.
ManyToManyField.through
Manually specify the intermediate table
ManyToManyField.db_table
Specify the name of the table in the database that stores the many-to-many relationship data. If this option is not provided, Django will generate a new table name based on the names of the two relational tables as the name of the intermediate table.
6.OneToOneField
class OneToOneField(othermodel[, parent_link=False, **options])
is used to define a one-to-one relationship. Broadly speaking, it is the same as a ForeignKey that declares unique=True Very similar, the difference is that when using reverse association, you get not a list of objects, but a single object.
This field is very useful when a model extends from another model; for example: Multi-table inheritance (Multi-tableinheritance) is passed in the child This is achieved by adding a one-to-one association to the model that points to the parent model.
You must give this field a parameter: the associated model class. Works the same as ForeignKey, including recursive and lazy associations it's the same.
Also, OneToOneField accepts ForeignKey acceptable parameters, only one parameter is OnetoOneField Proprietary: OneToOneField.parent_link
If it is True, and it acts on a child model inherited from a parent model (this cannot be delayed inheritance, the parent model must really exist ), then the field will become a reference (or link) pointing to the parent class instance, instead of being used to extend the parent class and inherit the parent class properties like other OneToOneFields.
from django.db import models, transaction, IntegrityError
class Place(models.Model):
name = models.CharField(max_length=50)
address = models.CharField(max_length=80)
def __unicode__(self ):
return u"%s the place" % self.name
class Restaurant(models.Model):
place = models.OneToOneField(Place, primary_key=True)
serves_hot_dogs = models.BooleanField()
serves_pizza = models .BooleanField()
def __unicode__(self):
return u"%s the restaurant" % self.place.name
class Waiter(models.Model):
restaurant = models.ForeignKey(Restaurant)
name = models .CharField(max_length=50)
def __unicode__(self):
When using reverse association, you get Not a list of objects, but a single object:
>>> p1 = Place(name='Demon Dogs', address='944 W. Fullerton')
>>> p1.save ()>>> r = Restaurant(place=p1, serves_hot_dogs=True, serves_pizza=False)
>>> r.save()
>>> p1.restaurant
< Restaurant: Demon Dogs the restaurant>
>>> Place.objects.get(restaurant__place__name__startswith="Demon")
>>> "Demon")
The above is the content in the Django document - Model. For more related articles, please pay attention to the PHP Chinese website (www.php.cn)!