Home > Backend Development > Python Tutorial > Django documentation - in Model

Django documentation - in Model

黄舟
Release: 2016-12-17 16:05:48
Original
1033 people have browsed it

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):

Return u"%s the waiter at %s" % (self.name, self.restaurant)



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)!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template