Django document -- ForeignKey, ManyToManyField, and OneToOneField in the Model

Source: Internet
Author: User

Relationship fields)

ForeignKey, ManyToManyField, and OneToOneField define multiple-to-one, multiple-to-many, one-to-one relationships in the Model respectively.

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. A single 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 a Model that has not been defined

If you want to associate with an undefined model, use the model name instead of the model object.

In this example, if Publisher and Author are defined after the Book, they must 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. Associate Model with itself

The Model can have many-to-one relationships with itself.

class People(models.Model):    name=models.CharField(max_length=20)    leader=models.ForeignKey('self',blank=True,null=True)

The Model can also have many-to-many relationships with itself.

class Person(models.Model):    friends = models.ManyToManyField("self")

By default, this association is symmetric. 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, you need to find a friend of p3 and use p3.friends. all () instead of p3.person _ set. all ().

If you want to cancel this symmetric relationship, set inclurical to False.

class Person2(models.Model):    friends=(models.ManyToManyField("self",symmetrical=False)

In this way, p3.person _ set. all () is required for querying p3 friends.

3. Reverse name related_name

Reverse name, used to point from the joined field to the joined Field

Some special syntaxes (some special syntax) can be used normally.

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 publisher1.pub. all () or author1.author. all () to query books in reverse mode using Publisher or Author ().

If you do not want to set a reverse relationship, set related_name to '+' or end with '+.

user = models.ForeignKey(User, related_name='+')

If multiple manytomanyfields point to the same Model, you cannot find out which ManyToManyField is used in reverse query of FOO_set. you can disable the reverse 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 preceding example, the table corresponding to the BOOK model has a publisher_id column.

You can explicitly specify db_column to change the column name of this field. However, you do not need to change the column name of the database unless you want to customize the SQL statement.

Many-to-many: Django creates an intermediate table to represent the ManyToManyField relationship. By default, the name of the intermediate table is composed of two Relational Tables.

Because some databases have limits on the table name length, the name of the intermediate table is automatically limited to 64 characters and contains a non-repeated hash string. This

It means that you may see a table name like book_authors_9cdf4. You can use the db_table option to manually specify the name of the intermediate table.

However, if you want to manually specify an intermediate table, you can use the through option to specify the model and use another model to manage the many-to-many relationship. This model is the model corresponding to the intermediate table:

class Person(models.Model):    name = models.CharField(max_length=128)    def __unicode__(self):        return self.nameclass Group(models.Model):    name = models.CharField(max_length=128)    members = models.ManyToManyField(Person, through='Membership')    def __unicode__(self):        return self.nameclass 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 is added to the group.

To establish the relationship between Person and Group, you cannot use add, create, or remove. Instead, you must 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 many-to-many relationships are associated with itself, the ForeignKey of the intermediate table can point to the same Model, but they must be regarded as both sides of ManyToManyField, rather than symmetric.Required rical = False.

5. Other parameters (Arguments)

5.1 ForeignKeyThe following optional parameters are accepted, which define how the link runs.

ForeignKey. limit_choices_to

It is a dictionary containing filtering conditions and corresponding values, used to filter associated objects in the Django management background. For example, use the datetime module of Python to filter out the correlated objects that do not meet the filtering conditions:

Limit_choices_to = {'pub _ date _ lte ': datetime. date. today}

Only associated objects of pub_date before the current date can be selected.

You can also use the Q object instead of the dictionary to implement more complex filtering. When limit_choices_to is a Q object, it is unavailable if you place the key field in raw_id_fields of ModelAdmin.

ForeignKey. to_field

Specifies the field in the associated object and the current link. By default, to_field points to the primary key of the associated object.

ForeignKey. on_delete

When the ForeignKey associated with a model object is deleted, this object will also be deleted in cascade mode by default.

user = models.ForeignKey(User, blank=True, null=True, on_delete=models.CASCADE)

CASCADE:Default value. The model object will be deleted along with the ForeignKey associated object.

SET_NULL: Set the ForeignKey field of the model object to null. Of course, you must set null to True.

SET_DEFAULT: Set the ForeignKey field of the model object to the default value.

Protect: A ProtectedError will be generated when the ForeignKey associated object is deleted, 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 ManyToManyFieldThe following optional parameters are accepted, which define how the link runs.

ManyToManyField. limit_choices_to

Same as ForeignKey. limit_choices_to.

Limit_choices_to does not work for the ManyToManyField specified by the through parameter.

ManyToManyField. semantic rical

It works only when multiple-to-multiple links are defined recursively.

ManyToManyField. through

Manually specify an intermediate table

ManyToManyField. db_table

Specifies the name of the table in which many-to-many relationship data is stored in the database. If this option is not provided, Django generates 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])

Defines a one-to-one relationship. In general, it is very similar to the ForeignKey that declares unique = True. The difference is that when we use reverse association, we get not a list of objects, but a separate object.

This field is useful when a model is extended from another model. For example, Multi-tableinheritance) it is implemented by adding a one-to-one association to the parent model in the child model.

This field must be assigned a parameter: The Associated model class. The work method is the same as ForeignKey, And the recursive and lazy connections are the same.

In addition, OneToOneField accepts the acceptable ForeignKey parameter. Only one parameter is proprietary to OnetoOneField: OneToOneField. parent_link

If this parameter is set to True, it applies to the child model that inherits from a parent model. (the parent model must exist because it cannot be inherited later ), this field becomes a reference (or link) pointing to the parent class instance ),

Instead of extending the parent class and inheriting the parent class attributes like other OneToOneField.

from django.db import models, transaction, IntegrityErrorclass Place(models.Model):    name = models.CharField(max_length=50)    address = models.CharField(max_length=80)    def __unicode__(self):        return u"%s the place" % self.nameclass 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.nameclass Waiter(models.Model):    restaurant = models.ForeignKey(Restaurant)    name = models.CharField(max_length=50)    def __unicode__(self):        return u"%s the waiter at %s" % (self.name, self.restaurant)

When using reverse association, we get not a list of objects, but a separate 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")<Place: Demon Dogs the place>>>> Waiter.objects.filter(restaurant__place__name__startswith="Demon")

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.