ORM查询总结:
models.Book.objects.filter(**kwargs): querySet [obj1,obj2] models.Book.objects.filter(**kwargs).values(**kwargs) : querySet [{},{},{}] models.Book.objects.filter(**kwargs).values_list(title) : querySet [(),(),()] 跨表查询总结: class Book(models.Model): title = models.CharField(max_length=32) publish=models.ForeignKey("Publish") # 创建一对多的外键字段 authorList=models.ManyToManyField("Author") # 多对多的关系,自动创建关系表 class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=32) class Author(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() ad=models.models.OneToOneField("AuthorDetail") class AuthorDetail(models.Model): tel=models.IntegerField() 基于对象关联查询: if 一对多查询(Book--Publish): 正向查询,按字段: book_obj.publish : 与这本书关联的出版社对象 book_obj.publish.addr: 与这本书关联的出版社的地址 反向查询,按表名_set publish_obj.book_set: 与这个出版社关联的书籍对象集合 publish_obj.book_set.all() :[obj1,obj2,....] if 一对一查询(Author---AuthorDetail): 正向查询,按字段: author_obj.ad : 与这个作者关联的作者详细信息对象 反向查询:按表名: author_detail_obj.author : 与这个作者详细对象关联的作者对象 if 多对多(Book----Author): 正向查询,按字段: book_obj.authorList.all(): 与这本书关联的所有这作者对象的集合 [obj1,obj2,....] 反向查询,按表名_set: author_obj.book_set.all() : 与这个作者关联的所有书籍对象的集合 基于双下滑线的跨表查询: if 一对多查询(Book--Publish): 正向查询,按字段: # 查询linux这本书的出版社的名字: models.Book.objects.all().filter(title="linux").values("publish__name") 反向查询:按表名: # 查询人民出版社出版过的所有书籍的名字 models.Publish.objects.filter(name="人民出版社出版").values("book__title") if 一对一查询(Author---AuthorDetail): 正向查询,按字段: models.Author.objects.filter(name="egon).values("ad__tel") 反向查询:按表名: models.AuthorDetail.objects.filter(tel="151").values("author__name") if 多对多(Book----Author): 正向查询,按字段: models.Book.objects.filter(title="python").values("authorList__name") [{},{},{},{}] 正向查询,按表名: models.Author.objects.filter(name="alex").values("book__price") 注意: publish=models.ForeignKey("Publish",related_name="bookList") authorlist=models.ManyToManyField("Author",related_name="bookList") ad=models.models.OneToOneField("AuthorDetail",related_name="authorInfo") 反向查询的时候都用:related_name 聚合查询: querySet().aggregate(聚合函数)------返回的是一个字典,不再是一个querySet Book.objects.all().aggregate(average_price=Avg('price')) 分组查询: querySet().annotate() --- 返回的是querySet #统计每一个出版社中最便宜的书籍的价格 sql: select Min(price) from book group by publish_id; ORM: models.Book.objects.values("publish__name").annotate(Min("price"))#annotate也是一个聚合函数这个用在前面有分组的情况 F查询 与 Q查询 F查询使用于字段值与字段值的查询比较,需要引入 from django.db.models import F models.Book.objects.filter()
在上面所有的例子中,我们构造的过滤器都只是将字段值与某个常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?
Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。
# 查询评论数大于收藏数的书籍 from django.db.models import F Book.objects.filter(commnetNum__lt=F('keepNum'))
Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。
# 查询评论数大于收藏数2倍的书籍 Book.objects.filter(commnetNum__lt=F('keepNum')*2)
修改操作也可以使用F函数,比如将每一本书的价格提高30元:
Book.objects.
all
().update(price
=
F(
"price"
)
+
30
)
Q查询
filter() 等方法中的关键字参数查询都是一起进行“AND” 的。 如果你需要执行更复杂的查询(例如OR 语句),你可以使用Q 对象。
from django.db.models import Q Q(title__startswith='Py')
Q 对象可以使用& 和| 操作符组合起来。当一个操作符在两个Q 对象上使用时,它产生一个新的Q 对象。
bookList=Book.objects.filter(Q(authors__name="yuan")|Q(authors__name="egon"))
等同于下面的SQL WHERE 子句:
WHERE name ="yuan" OR name ="egon"
你可以组合& 和| 操作符以及使用括号进行分组来编写任意复杂的Q 对象。同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询:
bookList=Book.objects.filter(Q(authors__name="yuan") & ~Q(publishDate__year=2017)).values_list("title")
查询函数可以混合使用Q 对象和关键字参数。所有提供给查询函数的参数(关键字参数或Q 对象)都将"AND”在一起。但是,如果出现Q 对象,它必须位于所有关键字参数的前面。例如:
bookList=Book.objects.filter(Q(publishDate__year=2016) | Q(publishDate__year=2017), title__icontains="python" )
cookies
建立一个登陆页面
models
from django.db import models # Create your models here. class UserInfo(models.Model): username =models.CharField(max_length=32) password =models.CharField(max_length=32)
views
from django.shortcuts import render,HttpResponse,redirect # Create your views here. from app01 import models def login(requset): if requset.method=="POST": username=requset.POST.get("user") password=requset.POST.get("pwd") ret=models.UserInfo.objects.filter(username=username,password=password) if ret:#如果通过验证,就走下面 obj=redirect("/home/")#给浏览器一个cookie在返回时 obj.set_cookie("is_login",True,20)#设置一个cookie,它是一个字典类型的 obj.set_cookie("username",username) return obj else: return redirect("/login/")#如果没有通过就跳转到登录页面 return render(requset,"login.html")#在登录时返回这个页面 def home(request): is_login=request.COOKIES.get("is_login",None)#判断这个页面是否带着cookie if is_login: username=request.COOKIES.get("username") return render(request, "home.html",locals()) else: return redirect("/login/") def add(request): is_login = request.COOKIES.get("is_login", None) if is_login: return HttpResponse("OK") else: return redirect("/login/")
template
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <form action="/login/" method="post"> {% csrf_token %}#处理Django跨站请求时用的 <p>姓名 <input type="text" name="user"></p> <p>密码 <input type="password" name="pwd"></p> <input type="submit"> </form> </body> </html>