Django基础(三)

 

#models.py
from django.db import models

class Book(models.Model):
    nid=models.AutoField(primary_key=True)
    title=models.CharField(max_length=32)
    pubDate=models.DateField()
    price=models.DecimalField(max_digits=6,decimal_places=2)
    read_num=models.IntegerField(default=0)
    comment_num=models.IntegerField(default=0)
    
    #书籍与出版社:一对多
    publisher=models.ForeignKey('Publish', related_name='bookList')

    #书籍与作者:多对多
    authors=models.ManyToManyField('Author')

    def __str__(self):
        return self.title

class Publish(models.Model):
    name=models.CharField(max_length=32)
    addr=models.CharField(max_length=32)
    tel=models.BigIntegerField()

    def __str__(self):
        return self.name

class Author(models.Model):
    name=models.CharField(max_length=32)
    age=models.IntegerField()
    tel=models.CharField(max_length=32)

    def __str__(self):
        return self.name

class AuthorDetail(models.Model):
    addr=models.CharField(max_length=32)
    author=models.OneToOneField('Author')

#生成的第三张表的表名是 app01_book_authors,但是我们不能直接操作这张表

ORM跨表添加

1.一对多添加

1.publish_obj=Publish.objects.get(id=2)
表.objects.create(title='python',publisher=publish_obj)
2.表.objects.create(title='python',publisher_id=2)

2.多对多添加

authors=models.ManyToManyField('Author')  #与这本书关联的作者对象集合

book_obj=models.Book.objects.create(title=title,pubDate=pubdate,price=price,publisher_id=publish_id)

#方式1
print(book_obj.authors.all())  #QuerySet  []
alex=models.Author.objects.get(name='alex')
egon=models.Author.objects.get(name='egon')
#绑定关系
book_obj.authors.add(alex,egon)   
print(book_obj.authors.all())  #QuerySet  [author_alex,author_egon]
#方式2
author_list=models.Author.objects.all()
book_obj.authors.add(*author_list)

#解除关系
book_obj=models.Book.objects.get(nid=14)
print(book_obj.authors.all())
alex=models.Author.objects.get(name='alex')
book_obj.authors.remove(alex)

author_list=models.Author.objects.filter(id__gt=1)
book_obj.authors.remove(*author_list)

#清空
book_obj.authors.clear()

ORM跨表查询

1.基于对象的跨表查询

正向查询按字段,反向查询按表名(小写)_set

一对多跨表查询

1.查询python这本书出版社的地址
book_obj=Book.objects.get(title=python)
book_obj.publisher.addr
多对多跨表查询

1.查询python这本书的所有作者的姓名和年龄

book_python=models.Book.objects.get(title='python')
author_list=book_python.authors.all()
for author in author_list:
    print(author.name,author.age)


book_python=models.Book.objects.filter(title='python')
for book_python in book_pythons:
    author_list=book_python.authors.all()
    for author in author_list:
        print(author.name,author.age)
1.查询人民出版社出版过的书籍名称及价格

pub_obj=models.Publish.objects.get(name='renmin')
book_list=pub_obj.book_set.all() 或 book_list=pub_obj.bookList.all() #Query  与这个出版社关联的所有书籍对象

for obj in book_list:
    print(obj.title,obj.price)


2.alex出版过的所有书籍的名称

alex=models.Author.objects.get(name='alex')
book_list=alex.book_set.all()
for book in book_list:
    print(book.title,book.price)
一对一正向查询

查询addr在沙河的作者
authorDetail=models.AuthorDetail.objects.get(addr='shahe')
print(authorDetail.author.name)


一对一反向查询:按表名(小写),不需要加_set

查询alex在哪里
alex=models.Author.objects.get(name='alex')
alex.authordetail.addr

2.基于双下划线的跨表查询

正向查询按字段,反向查询按关联的表名

#查询python这本书的价格
ret=models.Book.objects.filter(title='python').values('price','title')
print(ret)
#查询python这本书出版社的地址和名称

正向查询:按字段
ret2=models.Book.objects.filter(title='python').values_list('publisher__name','publisher__addr')
print(ret2)
反向查询:按表名
ret3=models.Publish.objects.filter(bookList__title='python').values_list('name','addr')
print(ret3)
#查询人民出版社出版过的所有书籍名称和价格
models.Book.objects.filter(publisher__name='renmin').values('title','price')

models.Publish.objects.filter(name='renmin').values('bookList__name','bookList_price')
#查询egon出版过的所有书籍的名字(多对多)
models.Author.objects.filter(name='egon').values('book__title')

models.Book.objects.filter(authors__name='egon').values('title')
#地址以沙河开头的作者出版过的所有书籍名称以及出版社名称
ret=models.Book.objects.filter(authors__authordetail__addr__startswith='sha').values('title','publisher__name')
print(ret.count())

聚合与分组

1.聚合函数 SUM AVG MIN MAX COUNT
2.聚合函数可以单独使用,不一定要和分组配合使用;只不过聚合函数与group by搭配

aggregate()

#单纯聚合函数
#计算所有图书的平均价格
from django.db.models import Avg,Count,Sum,Min,Max

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

annotate()  返回queryset

为QuerySet重的每一个对象都生成一个独立的汇总值
#统计每一本书的作者个数
ret=models.Book.objects.all().annotate(auathors_num=Count('authors'))
for obj in ret:
    print(obj.nid,obj.title,obj.author_num)


#查询每一个出版社出版过的所有书籍的总价格
ret=models.Publish.objects.all().annotate(priceSum=Sum('bookList__price'))
for obj in ret:
    print(obj.id,obj.name,obj.priceSum)
或
ret=models.Book.objects.all().values('publisher__name').annotate(priceSum=Sum('price')).values('publisher__name','priceSum')

F查询与Q查询

from django.db.models import F,Q

ret1=models.Book.objects.filter(comment_num__gt=50)
ret2=models.Book.objects.filter(comment_num__gt=F('read_num'))
#评论数大于2倍阅读数的文章
ret3=models.Book.objects.filter(comment_num__gt=F('read_num')*2)
#给每本书涨价10元
models.Book.objects.all().update(F('price')+10)
#查询评论数大于500或阅读数也大于50并且价格低于100
models.Book.objects.filter((Q(comment_num__gt=50)|Q(read_num__gt=50))&Q(price__lt=100))

 

posted @ 2017-11-23 09:02  -Ryan-  阅读(152)  评论(0编辑  收藏  举报