zoukankan      html  css  js  c++  java
  • 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>
     
  • 相关阅读:
    函数指针的比较
    C++代码
    C++/STL
    Video Downloader使用总结
    98五笔输入法总结
    优酷url的encode与decode
    Directory类总结
    申请GV以及相关
    不用客户端下载腾讯视频
    选择写作博客的原则
  • 原文地址:https://www.cnblogs.com/1a2a/p/7763034.html
Copyright © 2011-2022 走看看