Detailed explanation of Django_ model class (7)

Table of contents

1. Define attributes

Field Type

options

Two, query set

two features

queryset caching

limit queryset

3. Condition query

conditional operator

1) query equality

2) Fuzzy query

 3) Empty query

4) Range query

5) Compare query

6) Date query

F object

Q object

aggregate function

 4. Association query

Executing relational queries through objects

Executing relational queries through model classes

5. Execute native SQL queries

 6. Manager Manager

custom manager

The role of custom manager classes

 Relationship between model manager classes and model classes

 7. Meta options

Source code and other data acquisition methods


# 定义书籍模型类
class BookInfo(models.Model):
    btitle = models.CharField(max_length=20)    # 书籍名称
    bpub_date = models.DateField()              # 发布日期
    bread = models.IntegerField(default=0)      # 阅读量
    bcomment = models.IntegerField(default=0)   # 评论量
    isDelete = models.BooleanField(default=False)   # 逻辑删除


# 定义英雄模型类
class HeroInfo(models.Model):
    hname = models.CharField(max_length=20)     # 英雄姓名
    hgender = models.BooleanField(default=True)     # 英雄性别,True为男
    hcomment = models.CharField(max_length=200)     # 英雄描述信息
    hbook = models.ForeignKey(BookInfo, on_delete=models.DO_NOTHING)       # 英雄与书籍关系为一对多

All the following examples use the above two model classes

1. Define attributes

Django determines the following information based on the attribute's type:

  • The type of field supported by the currently selected database
  • The default html control to use when rendering admin forms
  • Minimal authentication on admin site

Django will create an auto-growth primary key column for the table. Each model can only have one primary key column. If you use an option to set a property as the primary key column, Django will not create an auto-growth primary key column.

The primary key column attribute created by default is id, which can be replaced by pk, and the full spelling of pk is primary key.

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

Attribute naming restrictions:

  • Cannot be a python reserved keyword.
  • Continuous underscores are not allowed, which is determined by the query method of django
  • When defining attributes, you need to specify the field type, and specify the options through the parameters of the field type. The syntax is as follows:
属性=models.字段类型(选项)

Field Type

When using it, you need to introduce the django.db.models package, and the field types are as follows:

  • AutoField: IntegerField that grows automatically, usually does not need to be specified, when not specified, Django will automatically create an auto-growth attribute named id.
  • BooleanField: Boolean field, the value is True or False.
  • CharField(max_length=character length): String.
    • The parameter max_length indicates the maximum number of characters.
  • TextField: Large text field, generally used when it exceeds 4000 characters.
  • IntegerField: integer.
  • DecimalField(max_digits=None, decimal_places=None): decimal floating point number.
    • The parameter max_digits represents the total number of digits.
    • The parameter decimal_places indicates the number of decimal places.
  • FloatField: floating point number.
  • DateField[auto_now=False, auto_now_add=False]):日期。
    • The parameter auto_now means that every time .save is executed to save the object, the field is automatically set to the current time (not the default backfill of the database) , which is used for the timestamp of "last modification". It always uses the current date, and the default is false.
    • The parameter auto_now_add indicates that when the object is created for the first time, the current time is automatically set for the timestamp of creation. It always uses the current date, and the default is false.
    • The parameters auto_now_add and auto_now are mutually exclusive, the combination will be wrong.
  • TimeField: time, the parameters are the same as DateField.
  • DateTimeField: date time, the parameters are the same as DateField.
  • FileField: upload file field.

options

Constraints on fields are implemented through options, the options are as follows:

  • null: If it is True, it means that it is allowed to be empty, and the default value is False.
  • blank: If True, the field is allowed to be blank, the default value is False.
    •   Note: null is a concept in the database category, and blank is in the form validation category.
  • db_column: the name of the field, if not specified, the name of the attribute is used.
  • db_index: If the value is True, an index will be created for this field in the table, and the default value is False.
  • default: default value.
  • primary_key: If it is True, the field will become the primary key field of the model. The default value is False, which is generally used as an option of AutoField.
  • unique: If True, this field must have a unique value in the table, the default value is False.

Two, query set

A query set represents a collection of objects obtained from the database. Calling certain filter methods on the manager will return a query set. The query set can contain zero, one or more filters. Filters limit the results of queries based on the given parameters. From a Sql perspective, querysets are equivalent to select statements, and filters are like where and limit clauses.

The filters that return the queryset are as follows:

  • all(): returns all data.
  • filter(): returns the data that meets the condition.
  • exclude(): returns data that does not meet the conditions, which is equivalent to the not keyword in the where part of the sql statement.
  • order_by(): Sort the results.

A filter that returns a single value is as follows:

  • get(): returns a single object that satisfies the condition
    • Raises a "ModelClass.DoesNotExist" exception if not found.
    • If multiple objects are returned, a "model class.MultipleObjectsReturned" exception will be raised.
  • count(): Returns the total number of current query results.
  • aggregate(): Aggregate, returning a dictionary.

Determine whether there is data in a certain query set:

  • exists(): Determine whether there is data in the query set, return True if there is, and return False if not.

two features

  • Lazy execution: Creating a query set will not access the database until the data is called. The data call includes iteration, serialization, and if.
  • Cache: Using the same query set, a database query will occur when it is used for the first time, and then the results will be cached, and the cached data will be used when the query set is used again.

Example: query all, edit the index view of booktest/views.py, run and view.

# 不会执行查询
books = BookInfo.objects.all()
# 调用时执行查询
for book in books:
    bid = book.id

queryset caching

Each queryset contains a cache to minimize access to the database.

In the newly created query set, the cache is empty. When the query set is evaluated for the first time, a database query will occur. Django will store the query result in the query set cache and return the requested result. Next, the query set evaluation will be Reuse results from cache.

limit queryset

The query set can be subscripted or sliced, which is equivalent to the limit and offset clauses in SQL.

Note: Negative indices are not supported.

Slicing a queryset returns a new queryset without executing the query immediately.

If you get an object, use [0] directly, which is equivalent to [0:1].get(), but if there is no data, [0] throws an IndexError exception, and [0:1].get() throws a DoesNotExist exception if there is no data .

Example: Obtain items 1 and 2, run and view.

list=BookInfo.objects.all()[0:2]

3. Condition query

conditional operator

1) query equality

exact : Indicates equality.

Example: Query the book numbered 1.

list=BookInfo.objects.filter(id__exact=1)  # 字段与运算符使用双下划线连接
可简写为:
list=BookInfo.objects.filter(id=1)

2) Fuzzy query

contains : Whether to include.

Example: Search for books whose titles contain 'biography'.

list = BookInfo.objects.filter(btitle__contains='传')

startswith, endswith : start or end with the specified value.

Example: Query books whose titles end with 'Department'

list = BookInfo.objects.filter(btitle__endswith='部')

The above operators are case-sensitive, adding i before these operators means case-insensitive, such as iexact, icontains, istartswith, iendswith

 3) Empty query

isnull : Whether it is null.

Example: Query books whose title is not empty.

list = BookInfo.objects.filter(btitle__isnull=False)

4) Range query

in : Whether to be included in the scope.

Example: Search for books numbered 1 or 3 or 5

list = BookInfo.objects.filter(id__in=[1, 3, 5])

5) Compare query

 gt, gte, lt, lte : greater than, greater than or equal to, less than, less than or equal to.

 Example: Query books with numbers greater than 3

list = BookInfo.objects.filter(id__gt=3)

Not equal to operator , use exclude() filter.

list = BookInfo.objects.exclude(id=3)

6) Date query

 year, month, day, week_day, hour, minute, second : Operate on attributes of date and time types.

 Example: Query books published in 1980.

list = BookInfo.objects.filter(bpub_date__year=1980)

Example: Query books published after January 1, 1980.

list = BookInfo.objects.filter(bpub_date__gt=date(1990, 1, 1))

F object

 The previous query is to compare the properties of the object with the constant value, how to compare the two properties? Available F objects are defined in django.db.models.

The syntax is as follows:

F(属性名)

Example: Query books whose reading volume is greater than or equal to the number of comments.

from django.db.models import F
...
list = BookInfo.objects.filter(bread__gte=F('bcomment'))

Arithmetic operations can be used on F objects.

Example: Query books whose reading volume is greater than twice the number of comments.

list = BookInfo.objects.filter(bread__gt=F('bcomment') * 2)

Q object

Multiple filters are called one by one to represent the logic and relationship, which is the same as the and keyword in the where part of the SQL statement.

Example: Query books whose reading volume is greater than 20 and whose number is less than 3.

list=BookInfo.objects.filter(bread__gt=20,id__lt=3)
list=BookInfo.objects.filter(bread__gt=20).filter(id__lt=3)

If you need to implement a logical or or query, you need to use the Q() object combined with the | operator, and the Q object is defined in django.db.models.

The syntax is as follows:

Q(属性名__运算符=值)

Example: To query books whose reading volume is greater than 20, rewrite it as a Q object as follows.

from django.db.models import Q
...
list = BookInfo.objects.filter(Q(bread__gt=20))

Q objects can be connected using & and |, & means logical and, and | means logical or.

Example: To query books whose reading volume is greater than 20, or whose number is less than 3, it can only be realized by using the Q object

list = BookInfo.objects.filter(Q(bread__gt=20) | Q(pk__lt=3))

The ~ operator can be used before the Q object to indicate not.

Example: Query books whose numbers are not equal to 3.

list = BookInfo.objects.filter(~Q(pk=3))

aggregate function

 Aggregate functions are called using the aggregate() filter. Aggregation functions include: Avg, Count, Max, Min, Sum, which are defined in django.db.models.

Example: Query the total reading volume of books.

from django.db.models import Sum
...
list = BookInfo.objects.aggregate(Sum('bread'))

Note that the return value of aggregate is a dictionary type, the format is as follows:

{'聚合类小写__属性名':值}
如:{'sum__bread':3}

The aggregate() filter is generally not used when using count.

Example: Query the total number of books.

list = BookInfo.objects.count()

Note that the return value of the count function is a number.

 4. Association query

There are three types of relationships in relational databases:

  • ForeignKey (model class name, on_delete=models.DO_NOTHING): Create a foreign key, a one-to-many relationship, and define fields on the many side. .

    • on_delete: When deleting data in the associated table, the behavior of the field associated with the current table
    • on_delete = models.CASCADE, # When deleting data in the primary key table, the foreign key table associated with it needs to be deleted first

    • on_delete = models.DO_NOTHING, # delete associated data, do nothing

    • on_delete = models.PROTECT, # delete the associated data, raise an error ProtectedError

    • on_delete = models.SET_NULL, # Delete the associated data, and set the associated value to null (the premise is that the FK field needs to be set to be nullable, the same applies to one-to-one)

    • on_delete = models.SET_DEFAULT, # Delete the associated data, and set the associated value to the default value (the premise is that the FK field needs to set the default value, and the same applies to one-to-one)

  • ManyToManyField: many-to-many, define the field at either end.
  • OneToOneField: One-to-one, define the field at either end.
  • Recursive associations can be maintained, specified with 'self', see "Self-Association" for details.

Executing relational queries through objects

Query the foreign key table according to the primary key table , the syntax is as follows:

主键表实例对象.外键表模型名称_set

Example: Query all hero information whose book id is 1.

b = BookInfo.objects.get(id=1)
b.heroinfo_set.all()    # 关联的模型类名需要小写

Equivalent to SQL statement: select * from booktest_heroinfo where hbook_id=(select id from booktest_bookinfo where id=1);

To query the primary key table based on the foreign key table , the syntax is as follows:

外键表实例对象.创建外键时的变量名称

Example: Query the books associated with the hero whose id is 5 in the table corresponding to HeroInfo

hero = HeroInfo.objects.get(pk=3)    # pk=3指的主键值为3
hero.hbook    #  HeroInfo模型类创建外键的变量是 hbook

Equivalent to SQL statement: select * from booktest_bookinfo where id=(select hbook_id from booktest_heroinfo where id=5);

Executing relational queries through model classes

To query the data of a model class by multiple model class conditions , the syntax is as follows:

关联模型类名小写__属性名__条件运算符=值

Example: Query books, and require the description of the hero in the book to contain 'six'.

BookInfo.objects.filter(heroinfo__hcontent__contains='六')

Equivalent to SQL statement: select * from booktest_bookinfo where id in (select hbook_id from booktest_heroinfo where hcomment like '%6%');

To query multi-model class data by a model class condition , the syntax is as follows:

一模型类关联属性名__一模型类属性名__条件运算符=值

Example: Query all heroes whose title is "Tian Long Ba Bu".

HeroInfo.objects.filter(hbook__btitle='天龙八部')

Equivalent to SQL statement: select * from booktest_heroinfo where hbook_id in (select id from booktest_bookinfo where btitle="Dragon Babu");

5. Execute native SQL queries

The official address for executing native SQL query documents: https://docs.djangoproject.com/zh-hans/3.1/topics/db/sql/

Using the manager method  raw() can be used to execute native SQL queries, the syntax is as follows:

 Manager.raw(sql, params=None, translations=None)

This method accepts a native SQL query statement, executes it, and returns an  django.db.models.query.RawQuerySet instance. This  can  be iterated over object instances RawQuerySet as normal  .QuerySet

Example: Query all books in BookInfo

books = BookInfo.objects.all()
# 等效于上面的代码
books = BookInfo.objects.raw('select * from booktest_bookinfo')

Example: Query all information about the books associated with the hero whose id is 7 in the table corresponding to HeroInfo

hero = HeroInfo.objects.get(pk=3)    # pk=3指的主键值为3
hero.hbook    #  HeroInfo模型类创建外键的变量是 hbook

# 等同于
BookInfo.objects.raw('select * from booktest_bookinfo where id=(select hbook_id from booktest_heroinfo where id=7)')
# 等同于
HeroInfo.objects.raw('select * from booktest_bookinfo where id=(select hbook_id from booktest_heroinfo where id=7)')

The following aspects need to be paid attention to when using raw() to execute:

1. When using raw(), what is queried is a  RawQuerySet QuerySet object, which can  be iterated to obtain object instances like ordinary ones  .

 2. Django will not  .raw() do any checks on the passed SQL statement. If the queried data does not exist, an empty object set will be returned instead of a prompt like the QuerySet  object

 3. If you need to execute parameterized queries, you can use  raw() parameters  params to prevent SQL injection

>>> id = 7
>>> books = HeroInfo.objects.raw('select * from booktest_bookinfo where id=(select hbook_id from booktest_heroinfo where id=%s)', [id])
>>> for book in books:
...     book.btitle
...
'天龙八部'
>>>

Do not write in the following style, there is a risk of SQL injection

>>> query ='select * from booktest_bookinfo where id=(select hbook_id from booktest_heroinfo where id=%s)' %id
>>>HeroInfo.objects.raw(query)

 6. Manager Manager

The previous queries are all through the model class.objects.query set, such as: BookInfo.objects.all() So what are objects? Objects is actually an instance object of the models.Manager class automatically generated by Django for us, that is, the manager, through which the query of data can be realized.

custom manager

 Since objects is an instance object, we can also define a manager ourselves. The custom manager steps are as follows:

  1. Customize a manager class that inherits the models.Manager class
  2. Create an instance object of the custom manager class in the model class

This instance object is our custom manager

Example: The manager of the custom BookInfo model class is book, and view all books

# 自定义模型管理类
class BookInfoManager(models.Manager):
    pass


# 定义书籍模型类
class BookInfo(models.Model):
    btitle = models.CharField(max_length=20)    # 书籍名称
    bpub_date = models.DateField()              # 发布日期
    bread = models.IntegerField(default=0)      # 阅读量
    bcomment = models.IntegerField(default=0)   # 评论量
    isDelete = models.BooleanField(default=False)   # 逻辑删除
    # 自定义模型管理器
    book = BookInfoManager()

    def __str__(self):
        return F"btitle:{self.btitle},bpub_date:{self.bpub_date}"

 As can be seen from the above figure, once we customize the manager, the objects manager will become invalid.

The role of custom manager classes

The above custom manager class completely inherits models.Manager without any modification, which is meaningless.

Custom manager classes are mainly used in two situations:

  1. Modify the original query set, such as rewriting the all() method
  2. Add additional methods in the manager class, such as inserting data into the database

1. Modify the original query set

For example: return books with isDelete equal to 0 in the database

Modify the above BookInfoManager to the following code:

class BookInfoManager(models.Manager):

    # 默认查询未删除的图书信息
    # 调用父类的成员语法为:super().方法名
    def all(self):
        return super().all().filter(isDelete=0)

Call the all() method in the shell

 2. Add additional methods to the manager class

For example: Create a create_book method that adds books in the manager class

# 自定义模型管理类
class BookInfoManager(models.Manager):

    # 默认查询未删除的图书信息
    # 调用父类的成员语法为:super().方法名
    def all(self):
        return super().all().filter(isDelete=0)

    def create_book(self, title, bpub_date):
        # 获取 self 所在的模型类。self此时表示实例化对象 objects ,objects所在的模型类就是 BookInfo,所以model_class此时指向的就是 BookInfo。
        # 使用此方法可以避免因模型类修改名称而导致的实例化找不到类对象的问题
        model_class = self.model
        # 创建实例对象
        book = model_class()
        # book = BookInfo()
        book.btitle = title
        book.bpub_date = bpub_date
        book.bread = 0
        book.bcomment = 0
        book.isDelete = 0
        book.save()

Note: The above custom management name has been changed from book to objects, and this objects is still a custom manager

 In addition to adding additional methods in the manager class, we can also add class methods in the model class BookInfo to achieve the same function, such as:

# 定义书籍模型类
class BookInfo(models.Model):
    ...

    @classmethod
    def cls_create_book(cls, title, bpub_date):
        # cls 此时代表的是 BookInfo 这个类,book=cls() 也就是 book=BookInfo()
        book = cls()
        book.btitle = title
        book.bpub_date = bpub_date
        book.bread = 0
        book.bcomment = 0
        book.isDelete = 0
        book.save()

 However, the model class is mainly to establish a corresponding relationship with the database table. If too many methods are encapsulated in the model class, there will be a lot of content in the model class that has nothing to do with the data table. In order to make the model class The relationship between the database table and the method of operating the database table are separated, so we add the method of operating the database table in the manager class.

Django has defined a general method create for us, which needs to pass in parameters in the form of key-value pairs:

 Relationship between model manager classes and model classes

Establish a connection by creating an instance object of the model manager class in the model class

 7. Meta options

The format of the data table created by the model class is: application name_model class name, for example, the model class BookInfo uses booktest_bookinfo as the table name in the database. At this point, if we change the name of the application to booktest2, then the table name corresponding to the model class becomes booktest2_bookinfo, but the table name corresponding to this model class has already been generated, and an error will be reported if we call this model class at this time.

We can specify the table name of the model class through the db_table of the meta option Meta. Once the table name is specified, the table created through the model class no longer depends on the application name.

# 定义书籍模型类
class BookInfo(models.Model):
    btitle = models.CharField(max_length=20)    # 书籍名称
    bpub_date = models.DateField()              # 发布日期
    bread = models.IntegerField(default=0)      # 阅读量
    bcomment = models.IntegerField(default=0)   # 评论量
    isDelete = models.BooleanField(default=False)   # 逻辑删除
    # 自定义模型管理器
    objects = BookInfoManager()

    class Meta:
        db_table = 'bookinfo'

db_table is just one of the commonly used django meta options. For more options, please refer to the official documentation: https://docs.djangoproject.com/zh-hans/3.1/ref/models/options/ 


Source code and other data acquisition methods

Friends who want to get the source code, please like + comment + favorite, triple!

After three times in a row , I will send you private messages one by one in the comment area~

Guess you like

Origin blog.csdn.net/GDYY3721/article/details/131623090