python-django框架ORM研究继续_20191111

python-django框架ORM研究继续

ORM回顾

1,ORM常用的字段和属性,

AutoField(primary_key=True)

CharField(max_length=20)

intgerField()

DateField()

DateTimeField()

auto_now_add,----每次新增的时候添加时间为当前时间,

auto_add----每次修改的时候更改时间,

2,关系字段

ForeignKey(to=‘表名’,ralated_name='xx')------一对多,通常设置在多的那一边,

ManyToMany(to=‘表名’)  ---多对多,通常是放在正向查询多的那一边,比如书和作者,把多对多放到了书的这边,因为根据书查作者比较多,

3,ORM一般操作

必知必会13条,

返回queryset对象的:

all()

filter()

values()返回一个字典

values_list()返回一个元组

exclude() 不包含

order_by()

reserve() 反转

distinct()

返回具体对象的

get()

first()

last()

----------

exist() 返回布尔

count()返回数量

4,单表查询下划线问题,

5,外键的跨表查询

正向查找,

  基于对象

book_obj=models.Book.objects.get(id=1)

book_obj.publisher.name

  基于下划线的,

book_obj=models.Book.objdects.filter(id=1).values("publisher__name")

反向查找

  基于对象

publisher_obj=models.Publisher.objects.get(id=1)

publisher_obj.book_set.all()

如果在外键中设置了related_name=books

publisher_obj.books.all()

  基于下划线的,

models.Publisher.objects.filter(id=1).values('book_title')

如果在外键中设置了related_name=books

models.Publisher.objects.filter(id=1).values("books_title")

6,分组和聚合,

聚合

models.Book.objects.all().aggregate(price_avg=Avg('price'))

分组:

models.Book.objects.all.annotate(author_num=Count('author'))

根据书分组,然后计算每一本书的作者的数量,

5,F和Q

F查询,字段和字段需要比较的时候需要用到F查询,

models.Book.objects.filter(inventory_num__gt=F('sales_num'))

Q查询

查询条件或的时候,使用Q查询,因为默认的filter都是且的关系,

6,事务,原子操作,

import os

if __name__ == '__main__':
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
import django
django.setup()

import datetime
from app01 import models

try:
  from django.db import transaction #导入一个transaction
  with transaction.atomic():  #atomic原子,下面的语句要么都成功,要么都不成功,这样就可以了,这就是事务,
    new_publisher = models.Publisher.objects.create(name="火星出版社")
    models.Book.objects.create(title="橘子物语", publish_date=datetime.date.today(), publisher_id=10) # 指定一个不存在的出版社id
except Exception as e:
  print(str(e))

7,执行原生的sql语句,

#执行原生的sql
ret = models.Book.objects.raw('select * from app01_book')
for i in ret:
print(i)

####################################################

orm一对一

detail=models.OneToOneField(to='AuthorDetail')

#一个作者对应一个作者详情,
#为什么这么做,因为作者表用的非常的频繁,每一次查的时候都要全表查,数据量大,但是用到的字段不多,
#所以把常用的字段抽离出来,
#比如列表页和详情页,这些都是需要分离的,为了更快的查询,

# orm多对多的三种方式


#多对多的方式
# 1,orm自动帮我创建第三张表,书和作者之间的第三张表就是自动创建的,
# 2,自己创建第三张表,利用外键分别关联作者和书,查询比较麻烦
# 3,自己创建第三张表,使用orm的manyTomanyField,制定一下,
# book=models.ManyToManyField(to='book',through='Author2Book',through_fields=("author","book"))
#第三种的查询方式和第一种的查询方式一样的,因为已经做了关联了,

# 我们使用第几种,
# 我们使用第几种,
#如果第三张表没有额外的字段,就使用第一种方法,
#如果第三张表有额外的字段,这种可以使用第三种方法和第一种方法,
# 比如相亲网站,一个男的可以联系多个女的,一个女的也可以联系多个男的,这就是多对多的,
#约会记录,多对多,这个表的结构,
#id boy_id girl_id date 约会时间,
#这种add() remove() 就没有了,

# 举例:
# 从作者关联的书里面移除id是1的书
# 之前使用第一种方法的时候是:
# models.Author.objects.get(id=1).book.remove(1)
# 现在自己建第三张表,就不能使用这种方式了,
# models.Author2Book.objects.get(author_id=1,book_id=1).delete()

#在app01里面查询id=1的作者关联的书,
# author_obj=models.Author.objects.get(id=4)
# ret=author_obj.book.all()
# print(ret)

#在app02里面查询id=1的作者关联的书,
# author_obj=models.Author.objects.get(id=4)
# ret=author_obj.book.all()
# print(ret)
#如果是你自己创建的第三张表,就不能使用这种方法了,因为里面没有book这个属性啊,
#怎么拿?
#先拿到作者为1的数据,在关联表
ret=models.Author2Book.objects.filter(author_id=4).values_list('book_id')
print(ret)#<QuerySet [(4,), (5,)]>
ret=[i[0] for i in ret] #看来列表推导式还是需要研究一下
ret=models.Book.objects.filter(id__in=ret)
print(ret)
#所以这种自己建立第三张表是比较麻烦的,

猜你喜欢

转载自www.cnblogs.com/andy0816/p/11837597.html