day53 Django multi-table queries, and lock service
Based on cross-table double-underlined query (join)
One to One
Even by the forward attribute table
Query Xudong home address
ret = models.Author.objects.filter(name='旭东').values('ad__addr')
print(ret)
If expressed in SQL statements, it should look like this:
select app01_authordetail.addr from app01_author inner join app01_authordetail on app01_author.ad_id = app01_authordetail.id where app01_author.name='旭东';
Even reverse the table class name in lowercase
ret = models.AuthorDetail.objects.filter(author__name='旭东').values('addr')
print(ret)
Many
The Tokyo publishing house published a book which
If the direct use of SQL statements should be written:
select app01_book.title from app01_publish inner join app01_book on app01_publish.id = app01_book.publishs_id where app01_publish.name='东京出版社';
The use of ORM, is written like this:
ret = models.Publish.objects.filter(name='东京出版社').values('book__title')
print(ret)
ret = models.Book.objects.filter(publishs__name='东京出版社').values('title')
print(ret)
Many to many
Inquiries about what book to write Jinlong 2
ret = models.Book.objects.filter(authors__name='金龙2').values('title')
print(ret)
ret = models.Author.objects.filter(name='金龙2').values('book__title')
print(ret)
Aggregate query
aggregate聚合查询,结果是普通字典,queryset的结束符
from django.db.models import Avg,Max,Min,Count,Sum
obj = models.Book.objects.all().aggregate(a=Max('price')) #{'price__avg': 200.0}
print(obj)
Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
Grouping queries
Grouping queries written in SQL statement should be:
group by app01_book.publishs_id
For example: find the highest price of each book published by
Mode 1
ret = models.Book.objects.values('publishs_id').annotate(m=Max('price'))
print(ret)
Summary: values written on the front annotate, meaning based on field values in parentheses as the basis for grouping. annotate there is statistical results you have to do. Thus, the result is returned queryset type data, which is a dictionary:
{'publishs_id':1,'m':100}
Mode 2
ret = models.Publish.objects.annotate(m=Max('book__price')).values('m','name')
print(ret)
Summary: annotate directly written on the back of objects, meaning that all of the data in accordance with the previous table (the default is id value) of the grouping. Return result is that all models objects in front of the table (each object contains its statistical model object), and then to the value by values. Fields can write and direct statistical results when the value of an alias, also queryset type, which is the dictionary:
{'m':100,'name':'东京出版社'}
Queries highest price for each author's name and the publication of the book:
ret = models.Book.objects.values('authors__name','authors__id').annotate(m=Max('price')) # group by authors__name,authors__id
print(ret)
ret = models.Author.objects.annotate(m=Max('book__price')).values('name','m')
print(ret)
Query F
F is the result of the query result set qualified after comparison of the two fields in this table
Like point is greater than the number of inquiries about all the books the number of comments.
In the past, we can also be found by using a loop:
list1 = []
books = models.Book.objects.all()
for i in books:
if i.dianzan > i.comment:
list1.append(i)
If you are using F query, the code will be more simple and intuitive:
ret = models.Book.objects.filter(dianzan__gt=F('comment')).values('title')
ret = models.Book.objects.filter(dianzan__lt=F('comment')).values('title')
print(ret)
This four operations Field
models.Book.objects.all().update(
price=F('price') + 20 # 支持四则运算
)
Q query
Performs a logical operation for the query Q, Q of the connector:
& -- and
| -- or
~ -- not,取反
Like inquiries about point greater than 300 or less than the price of the book 300
ret = models.Book.objects.filter(Q(dianzan__gt=300)|~Q(price__lt=500),xx='oo').values('title')
ret = models.Book.objects.filter(Q(dianzan__gt=300)).values('title')
ret = models.Book.objects.filter(Q(Q(dianzan__gt=300)|~Q(price__lt=500))&Q(xx='oo')).values('title') # Q查询能够进行各种复杂条件的拼接
print(ret)
ORM execute native SQL statements (understand)
Mode 1
ret = models.Book.objects.raw('select * from app01_book;')
for i in ret:
print(i.title)
print(ret)
Embodiment 2 Django own connection passage (pymysql configuration)
from django.db import connection
import pymysql
conn = pymysq.connect()
cursor = connection.cursor()
cursor.execute('select * from app01_book;')
print(cursor.fetchall())
3 pymysql way
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='root',
password='123',
database='orm02',
charset='utf8',
)
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute('select * from app01_book;')
print(cursor.fetchall())
Django database operations outside of the script models
import os
if __name__ == '__main__':
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm02.settings")
import django
django.setup()
from app01 import models
ret = models.Book.objects.all().values('title')
print(ret)
ORM affairs and lock
lock
We can give the code shackles:
models.Book.objects.select_for_update().filter(id=1)
Affairs
Global Configuration Mode 1
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mxshop',
'HOST': '127.0.0.1',
'PORT': '3306',
'USER': 'root',
'PASSWORD': '123',
"ATOMIC_REQUESTS": True, #全局开启事务,绑定的是http请求响应整个过程当中的sql
}
}
Embodiment 2 plus view function decorator
from django.db import transaction
@transaction.atomic
def viewfunc(request):
# This code executes inside a transaction.
do_stuff()
Embodiment 3 plus context decorator
from django.db import transaction
def viewfunc(request):
# This code executes in autocommit mode (Django's default).
do_stuff()
with transaction.atomic(): #保存点
# This code executes inside a transaction.
do_more_stuff()
do_other_stuff()