Django之ORM查询复习与cookie

Posted 黎明NB

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django之ORM查询复习与cookie相关的知识,希望对你有一定的参考价值。

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 语句),你可以使用对象
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>

 

 

 

以上是关于Django之ORM查询复习与cookie的主要内容,如果未能解决你的问题,请参考以下文章

django--模型层(orm)-查询补充及cookie

Django ORM 之FQ查询与事务

Django之ORM查询进阶

django之ORM的查询优化,Ajax

(Django)气流中的 ORM - 有可能吗?

Django之orm查询