Coding With Fun
Home Docker Django Node.js Articles Python pip guide FAQ Policy

Django model


May 14, 2021 Django


Table of contents


Brief introduction

The model is the only defined source of information about the data. I t contains the basic fields and behaviors to store the data. Typically, each model is mapped to a single database table.

  • Each model is a .db of django.models.Model
  • Each model property represents a field in the data table.
  • Django provides an automatically generated database access API, and it's easy to manipulate the database using models

A quick example

This sample model defines a Person that contains first_name and last_name

from django.db import models

class Person(models.Model):
    first_name = models.CharField(max_length=30)
    last_name = models.CharField(max_length=30)

first_name and last_name is a field model. Each field is specified as a class property, and each property is mapped to a database column.

The Person model above creates a database table that looks like this:

CREATE TABLE myapp_person (
    "id" serial NOT NULL PRIMARY KEY,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL
);
Some technical notes:
  • The name myapp_person table is automatically derived from some model metadata, but can be overwritten.
  • An id field is automatically added, but this behavior can be overwritten.
  • In this example, SQL is formatted using postgreSQL syntax, but it's worth noting that Django uses SQL customized for the database backend specified in the settings file. CREATE TABLE

For more information, please refer to the official website: https://docs.djangoproject.com/en/3.0/topics/db/models/

Define the model

Django determines the following information based on the type of property:

  • The type of database support field that is currently selected
  • The default html control used when rendering management forms
  • Minimal validation at the management site

Django creates an auto-growing primary key column for the table, each model can have only one primary key column, and if you use the option to set a property for the primary key column, django no longer creates an auto-growing primary key column.

The primary key column property created by default is id, which can be replaced with pk, which is spelled as primary key.

pk is the alias of the primary key, and if the primary key is named id2, then pk is the alias of id2.

Property naming restrictions:

  • Cannot be a reserved keyword for python.
  • Continuous underscores are not allowed, as determined by django's query, which is explained in detail in Section 4.
  • When you define a property, you need to specify the field type and specify the options through the parameters of the field type.

The syntax is as follows:

Property s models.field type (options)

The model field class table

The field class The default team piece Description
AutoField N/A Integer Field that automatically increments based on ID
BigIntegerField NumberInput 64-bit integer, much like Integer Field, but with values ranging from -9223372036854775808 to 9223372036854775807.
BinaryField N/A The field where the original binary data is stored. O nly bytes types are supported. Note that this field has limited functionality.
BooleanField CheckboxInput True or false value field. If you want to accept the null value, use NullBoolean Field.
CharField TextInput String field, for strings with smaller lengths. A large amount of text should use TextField. There is an additional must-have max_length, which is the maximum length of the field (number of characters).
DateField DateInput Date, represented by a datetime.date instance in Python. There are two additional optional parameters: auto_now, which is automatically set to the current date auto_now_add each time the object is saved, and to the current date when the object is created.
DateTimeField DateTimeInput Date and time, represented in Python using the datetime.datetime instance. Has the same extra parameters as DateField.
DecimalField TextInput A fixed number of decimals, represented by a Decimal instance in Python. There are two necessary parameters: max_digits and decimal_places.
DurationField TextInput Storage time span, represented by timedelta in Python.
EmailField TextInput A CharField that uses EmailValidator to validate input. max_length default value for the data is 254.
FileField ClearableFileInput File upload field. See below for details.
FilePathField Select A CharField that restricts the selection of files only in a specific directory in the file system.
FloatField NumberInput Floating points, represented by float instances in Python. Note that when the value of field.localize is False, the default component is TextInput.
ImageField ClearableFileInput All properties and methods are inherited from FileField, in addition to verifying that the uploaded object is not a valid image. T wo properties, height and width, have been added. Pillow library support is required.

Field options

  • Field options allow you to constrain fields
  • Specified by keyword parameters when field objects
  • null: If it's True, Django stores the empty value in NULL into the database, and the default is False
  • Blank: If true, the field is allowed to be blank, and the default is False
  • Comparison: null is the concept of database category, blank is form verification category
  • db_column: The name of the field, and if not specified, the name of the property is used
  • db_index: If the value is True, an index is created for this field in the table
  • Default: Default
  • primary_key: True, the field becomes the primary key field of the model
  • unique: If true, this field must have a unique value in the table

The association

Many-to-One (ForeignKey)

Django provides ways to define some of the most common database associations: many-to-one, many-to-many, one-to-one.

A many-to-one relationship requires two positional parameters, one for the associated model on_delete with foreign keys to be defined on multiple sides, such as a car factory producing multiple cars and a car with only one manufacturer

from django.db import models

class Manufacturer(models.Model):

    # ...

    pass

class Car(models.Model):

    manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)

Additional field for many-to-many relationships: throuth

For example, an app that records the music group to which the musician belongs. W e can use a ManyToManyField to represent a many-to-many relationship between a group and a member. However, sometimes you may want to know more details about membership, such as when a member joined the group.

For these cases, Django allows you to specify a mediation model to define many-to-many relationships. Y ou can put other fields in the mediation model. T he ManyToManyField field of the source model points to the mediation model using the trough parameter. For the music group example above, the code is as follows:

from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

    def __str__(self):              # __unicode__ on Python 2
        return self.name

class Membership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

When you set up an intermediate model, you explicitly specify foreign keys for the intermediate model involved in a many-to-many relationship. This explicit declaration defines how the two models are related.

There are some limitations in the intermediate model:

  • You either have and only have one foreign key in the middle of your model that points to the source model (Group in our example), you either have to manually select a foreign key among multiple foreign keys through the ManyToManyField.through_fields parameter, or you will get a validation error if the external multi-keyboard does not use the through_fields parameter. The same limitations are placed on the foreign keys of a target model (Person in our example).
  • In an intermediate model that points itself to its own many-to-many relationships in a useful description model, there can be two external healths pointing to the same model, but these two external health scales represent both ends of the many-to-many relationship (different). If the number of external health is more than two, you must specify the same parameters as through_fields above, otherwise there will be a validation error.

Now that you've completed your ManyToMany Field (Membership in the example) with the intermediate model, you're ready to start creating some many-to-many relationships. You create relationships by instantiated intermediate models:

>>> 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()
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>]>
>>> ringo.group_set.all()
<QuerySet [<Group: The Beatles>]>
>>> m2 = Membership.objects.create(person=paul, group=beatles,
...     date_joined=date(1960, 8, 1),
...     invite_reason="Wanted to form a band.")
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]>
You can add() using create() set() as long as you specify a value for through_defaults
>>> beatles.members.add(john, through_defaults={'date_joined': date(1960, 8, 1)})
>>> beatles.members.create(name="George Harrison", through_defaults={'date_joined': date(1960, 8, 1)})
>>> beatles.members.set([john, paul, ringo, george], through_defaults={'date_joined': date(1960, 8, 1)})

You may be more likely to create intermediate models directly.

If the custom intermediate model does not enforce the uniqueness of the pair, the calling method removes all instances of the intermediate model: (model1, model2) remove()

>>> Membership.objects.create(person=ringo, group=beatles,
...     date_joined=date(1968, 9, 4),
...     invite_reason="You've been gone for a month and we miss you.")
>>> beatles.members.all()
<QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>, <Person: Ringo Starr>]>
>>> # This deletes both of the intermediate model instances for Ringo Starr
>>> beatles.members.remove(ringo)
>>> beatles.members.all()
<QuerySet [<Person: Paul McCartney>]>

Method clear() all many-to-many relationships of an instance:

>>> # Beatles have broken up
>>> beatles.members.clear()
>>> # Note that this deletes the intermediate model instances
>>> Membership.objects.all()
<QuerySet []>

Once you have established a custom many-to-many association, you can perform query operations. As with a typical many-to-many association, you can query with the properties of a many-to-many association model:

# Find all the groups with a member whose name starts with 'Paul'
>>> Group.objects.filter(members__name__startswith='Paul')
<QuerySet [<Group: The Beatles>]>

When you use an intermediate model, you can also query his properties:

# Find all the members of the Beatles that joined after 1 Jan 1961
>>> Person.objects.filter(
...     group__name='The Beatles',
...     membership__date_joined__gt=date(1961,1,1))
<QuerySet [<Person: Ringo Starr]>

If you want to access information about a relationship, you can query the Membership model directly:

>>> ringos_membership = Membership.objects.get(group=beatles, person=ringo)
>>> ringos_membership.date_joined
datetime.date(1962, 8, 16)
>>> ringos_membership.invite_reason
'Needed a new drummer.'

Another way to access the same information is to query for many-to-many recursive relationships through theErson object:

>>> ringos_membership = ringo.membership_set.get(group=beatles)
>>> ringos_membership.date_joined
datetime.date(1962, 8, 16)
>>> ringos_membership.invite_reason
'Needed a new drummer.'

One-to-one association

Use OneToOneField to define one-to-one relationships. Just like with other types of Fields: include it in model properties.

The primary key of an object is useful when one object somehow "inherits" another object.

OneToOneField requires a location parameter: a class related to the model.

For example, when you want to build a database of "location" information, you might include the usual address, phone, and other branches. Then, if you want to go on to build a database about restaurants, in addition to copying a portion of the location database to the Restaurant model, you can also put a point to Place OneToOneField in Restaurant (because the restaurant is "a" location);

Like ForeignKey, you can create self-association relationships or relationships with models that have not yet been defined.

OneToOneField also initially accepted an optional parent_link parameters.

The OneToOneField class usually automatically becomes the primary key of the model, a rule that is no longer in use (and you can manually specify primary_key parameters). As a result, you can now specify multiple OneToOneField segments in the model.


For more information, please refer to the official website: https://www.khan.pub/django3.0/index.html