Django queryset several unusual APIs

Time:2021-11-28

1、related_name
Django also has a way to access associated table data through objects, that is, using_set。 However, this method can only be used for related classes to access classes with defined relationships (primary key classes access foreign key classes).

class Blog(models.Model):
    pass

class Entry(models.Model):
    blog = models.ForeignKey(Blog)

For example:b.entry_set.all()B is a blog object

In addition, if the definition of blog attribute in the entry is changed to this:blog=models.ForeignKey(Blog,related_name='entries')In this way, you can get a collection of entry objects through the blog object as follows:

b=Blog.objects.get(id=1)

b.entries.all() #==b.entry_set.all()# b.entries is a Manager that returns QuerySets.

b.entries.filter(headline__contains='Lennon')

b.entries.count()

2、Values and values_ list
Returns a similar list and dictionary form

Blog.objects.values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}],
Blog.objects.values('id', 'name')
[{'id': 1, 'name': 'Beatles Blog'}]

3、selected_related()
useselected_related()It will automatically query the relationship of relevant foreign keys, which may reduce the number of database queries.

#Query database
e = Entry.objects.get(id=5)
#The database will be queried again
b = e.blog

#Query database
e = Entry.objects.select_related().get(id=5)
#Will not query the database
b = e.blog

reference resources
https://docs.djangoproject.com/en/1.6/ref/models/querysets/#django.db.models.query.QuerySet.select_related

4、select_for_update
In case of partial concurrency, we must lock the records before updating the data,select_for_updateYou can do this.

All matched entries will be locked until the end of the transaction block, meaning that other transactions will be prevented from changing or acquiring locks on them.

Usually, if another transaction has already acquired a lock on one of the selected rows, the query will block until the lock is released. If this is not the behavior you want, call select_for_update(nowait=True). This will make the call non-blocking. If a conflicting lock is already acquired by another transaction, DatabaseError will be raised when the queryset is evaluated.

Currently, the postgresql_psycopg2, oracle, and mysql database backends support select_for_update(). However, MySQL has no support for the nowait argument. Obviously, users of external third-party backends should check with their backend’s documentation for specifics in those cases.

Passing nowait=True to select_for_update() using database backends that do not support nowait, such as MySQL, will cause a DatabaseError to be raised. This is in order to prevent code unexpectedly blocking.

5、bulk_create
This can create multiple records during a database query

Entry.objects.bulk_create([
     Entry(headline="Django 1.0 Released"),
     Entry(headline="Django 1.1 Announced"),
     Entry(headline="Breaking: Django is awesome")
])

6、

gt
Greater than.

Example:

Entry.objects.filter(id__gt=4)
SQL equivalent:

SELECT ... WHERE id > 4;
gte
Greater than or equal to.

lt
Less than.

lte
Less than or equal to.

7. Note that when using date to query the range of datetimefield, the range of the last day is not included. for example

import datetime
start_date = datetime.date(2005, 1, 1)
end_date = datetime.date(2005, 3, 31)
Entry.objects.filter(pub_date__range=(start_date, end_date))

Such SQL statements will be generated at this time
SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';
If the start inside_ When date is datetimefield, such SQL statements will be generated
SELECT ... WHERE pub_date BETWEEN '2005-01-01 00:00:00' and '2005-03-31 00:00:00';