多表操作、其他字段和字段参数、django与ajax(回顾)

多表操作

1 基于对象的跨表查

子查询----》执行了两句sql,没有连表操作

2 基于双下滑线的连表查

一次查询,连表操作

3 正向和反向

python 复制代码
放在ForeignKey,OneToOneField,ManyToManyField的
        -related_name='books':双下滑线连表查询,反向查询按表名小写---》用来替换表名小写
        	publish__books__name
        -related_query_name='books':基于对象跨表查,反向查询---》用来替换表名小写
        	pubilsh.book_set.all()
            pubilsh.books.all()

4聚合查询

  • aggregate是 QuerySet 的一个终止子句,用来做聚合查询
  • 聚合函数:Avg,Count,Min,Max,Sum
python 复制代码
    -使用
    	select name,price,avg('price') as price__avg from book; 
    	Book.objects.all().aggregate(Avg('price'))
        select name,price,avg('price') as average_price from book; 
        Book.objects.aggregate(average_price=Avg('price'))
        ret = Book.objects.all().aggregate(avg_price=Avg('price'), min_price=Min('price'))

5 分组查询--》分组后通常会用聚合---》annotate用来分组和聚合的

  • annotate:
    • filter在annotate前:表示过滤,where条件
    • values在annotate前:表示分组的字段,如果不写表示按整个表分组
    • filter在annotate后:表示 having条件
    • values在annotate后:表示取字段---》只能取分组字段和聚合函数字段
  • 分组的目的:把有相同特征的分成一组,分成一组后一般用来:统计总条数,统计平均数,求最大值
python 复制代码
    -统计每一本书作者个数---》 Book.objects.all().values('id').annotate(author_num=Count("authors")).values('name','author_num')
    
    -统计每一个出版社的最便宜的书---》按出版社
    Publish.objects.all().valuse('id').annotate(min_price=Min("book__price")).vlaues('name','min_price')
 Publish.objects.annotate(MinPrice=Min("book__price"))


	-查询每一个书籍的名称,以及对应的作者个数-->按书分
    Book.objects.all().values('id').annotate(count_publish=Count("authors")).value('name','count_publish')
    
    -查询每一个以 红开头 书籍的名称,以及对应的作者个数-->按书分
     Book.objects.all().filter(name__startswith='红')values('id').annotate(count_publish=Count("authors")).value('name','count_publish')
        
        
   -查询每一个以 红开头 书籍的名称,以及对应的作者个数大于3的记录-->按书分
Book.objects.all().filter(name__startswith='红')values('id').annotate(count_publish=Count("authors")).filter(count_publish__gt=3).value('name','count_publish')

6 F查询与Q查询

  • F查询:拿到某个字段在表中具体的值
    *

    python 复制代码
            -查询评论数大于收藏数的书籍
            from django.db.models import F
            Book.objects.filter(评论数__gt=F('收藏数'))
            -让所有图书价格 +1
            Book.objects.all().update(price=F('price')+1)
  • Q查询:为了组装成 与 或 非 条件
    *

    python 复制代码
    		-与条件:and条件,在filter中直接写---》就是and条件
        		Book.objects.filter(authors__name="lqz",price=100)
        	-或条件:Book.objects.filter(Q(authors__name="lqz")|Q(authors__name="justin"))
            -非条件:Book.objects.filter(~Q(name='红楼梦'))
            
            -复杂逻辑:(名字为红楼梦并且价格大于100) 或者 id 大于 2
            Book.objects.filter((Q(name='红楼梦') & Q(price__gt=100))|Q(nid__gt=2))

其他字段和字段参数

字段参数;ORM字段参数

  • null用于表示某个字段可以为空。
  • unique 如果设置为unique=True 则该字段在此表中必须是唯一的 。
  • db_index如果db_index=True 则代表着为此字段设置索引。
  • default为该字段设置默认值。
  • DateField和DateTimeField
    • auto_now_add=True:新增会把当前时间存入
    • default=datatime.datatime.now
    • auto_now=True,每次更新数据记录的时候会更新该字段
  • verbose_name 提示,该字段的作用
  • blank Admin中是否允许用户输入为空
  • editable Admin中是否可以编辑
  • help_text Admin中该字段的提示信息
  • choices Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
    • get_字段名_display()

ForeignKey 属性

to设置要关联的表

to_field 设置要关联的表的字段

related_name 反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'。

related_query_name 反向查询操作时,使用的连接前缀,用于替换表名。

on_delete

当删除关联表中的数据时,当前表与其关联的行的行为。

models.CASCADE删除关联数据,与之关联也删除

models.DO_NOTHING 删除关联数据,引发错误IntegrityError

models.PROTECT 删除关联数据,引发错误ProtectedError

models.SET_NULL删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)

models.SET_DEFAULT删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)

models.SET

删除关联数据,

a. 与之关联的值设置为指定值,设置:models.SET(值)

b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

db_constraint---》公司一般都设置为False

是否在数据库中创建外键约束,默认为True

db_constraint=False 在数据库中不建立外键约束

虽然不建立数据库外键约束---》但是orm查询,继续用

ManyToManyField

用于表示多对多的关联关系。在数据库中通过第三张表来建立关联关系

to 设置要关联的表中间是有个中间表的,区别于一对多

related_name 同ForeignKey字段。

related_query_name 同ForeignKey字段。

through

在使用ManyToManyField字段时,Django将自动生成一张表来管理多对多的关联关系。

但我们也可以手动创建第三张表来管理多对多关系,此时就需要通过through来指定第三张表的表名。

through_fields设置关联的字段

db_table 默认创建第三张表时,数据库中表的名称。

中间表创建方式

自动生成:用不到through 和 through_fields
python 复制代码
authors=models.ManyToManyField(to='Author',db_table='中间表表名')
  • 自动创建中间表,有快捷操作
    • add
    • remove
    • set
    • clear
python 复制代码
        book表
        id   name           price
        1    西游记           22
        2    红楼梦           33
        
        bookToauthors
        id  book_id   author_id  
        1    1            1
        2    1            2
        
        author表
        id   name    gender    age
        1    lqz      男        18
        2    罗贯中    女        22
手动创建中间表,使用through指定

三张表都要手动创建--》3个类--》3个表模型---》

什么情况会使用手动创建?----中间表如果有多的字段,都是手动创建

python 复制代码
    authors=models.ManyToManyField(to='Author',through='booktoauthor', through_fields=('当前表--》到中间表的外键关系','剩下的写在第二个位置'))
python 复制代码
        book表
        id   name           price
        1    西游记           22
        2    红楼梦           33
        
        booktoauthor
        id  book_id   author_id   日期
        1    1            1       
        2    1            2
        
        author表
        id   name    gender    age
        1    lqz      男        18
        2    罗贯中    女        22
纯手动创建中间表,不使用ManyToManyField关联

不会在book或author表中加 ManyToManyField 字段了

python 复制代码
         book表
        id   name           price
        1    西游记           22
        2    红楼梦           33
        
        booktoauthor
        id  book_id   author_id   日期
        1    1            1       
        2    1            2
        
        author表
        id   name    gender    age
        1    lqz      男        18
        2    罗贯中    女        22

在表中都可以定义要给内部类

python 复制代码
class Author(models.Model):
    name = models.CharField(max_length=32)
    class Meta:  #元信息
        db_table
        index_together
        unique_together
        ordering # 默认按id排序

django与ajax

ajax:异步Javascript和XML

**作用:**Javascript语言与服务器(django)进行异步交互,传输的数据为XML(当然,传输的数据不只是XML,现在更多使用json数据)

同步交互,异步交互

同步交互:js发送出请求---》直到请求回来---》页面不能操作,不能点击

异步交互:js发出请求---》等待请求回来的过程中--->页面可以随意继续操作

**使用:**使用了jq帮咱们封装的方法 ajax ,名字跟ajax相同 $.ajax

真正的ajax原生,需要使用js操作,jq的ajax方法是对原生js的封装,方便咱们使用

-前后端混合项目中,我们通常使用jq的ajax实现 js和后端异步交互

-jq操作dom

-jq发ajax请求

-前后端分离项目中,我们会使用另一个第三方库,实现 js和后端异步交互(axios)

-只想发送ajax请求---》只用来发ajax请求的库

计算 + 小案例

  • demo01.html
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

<h1>写一个计算小案例--ajax</h1>
<input type="text"name="one" id="one"> + <input type="text"name="two" id="two"> = <input type="text"name="three"id="three">
<button id = 'id_btn'>计算</button>
</body>
<script>
    $("#id_btn").click(function (){
        {#alert("xxx")#}
        var one=$("#one").val()
        var two=$("#two").val()
        $.ajax({
            url:'/demo01/',
            method:'post',
            data:{one,two},
            success:function (res){
                console.log(typeof res)
                if (res.code==100){
                    $("#three").val(res.result)
                }else {
                    alert(res.msg)
                }
            }
        })
    })
</script>
</html>
python 复制代码
def demo01(requset):
    if requset.method=='GET':
        return render(requset,'demo01.html')
    else:
        one=int(requset.POST.get('one'))
        two=int(requset.POST.get('two'))
        return JsonResponse({'code':100,'msg':'计算成功','result':one+two})

上传文件

  • demo01.html
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>

<hr>
<h1>文件上传</h1>
<input type="file" id="id_file"><button id="id_submit">文件上传</button>
</body>
<script>
        $("#id_submit").click(function (){
            {#alert("xxx")#}
            var formdata = new FormData()
            //$('#id_file')[0].files[0]
            //$('#id_file')根据id拿到标签---------》jq把标签放到一个列表中,
            //取第0个位置,是取出第一个符合条件【id为id_file】的标签,想拿文件---》标签对象.files--->对象---》从对象中取出key为0队友的文件对象
            formdata.append('myfile',$('#id_file')[0].files[0])
        $.ajax({
            url:'/demo01/',
            method:'post',
            //指定编码上传文件
            processData: false,
            contentDocument:false,
            data:formdata,
            success:function (res){
                if (res.code==100){
                    alert(res.msg)
                }else {
                    alert(res.msg)
                }
            }
        })
    })
</script>
</html>
python 复制代码
def demo01(requset):
    if requset.method=='GET':
        return render(requset,'demo01.html')
    else:
        myfile=requset.FILES.get('myfile')
        with open(myfile.name,'wb') as f:
            for line in myfile:
                f.write(line)
        return JsonResponse({'code':100,'msg':'文件上传成功',})

json格式用的多,后期

python 复制代码
	      $.ajax({
            url: '/demo01/',
            method: 'post',
            contentType: 'application/json',
            data: JSON.stringify({name: 'lqz', age: 19}), // 把对象转成字符串形式,json格式字符串
            success: function (data) {
                console.log(data)
            }
        })
相关推荐
宋发元23 分钟前
如何使用正则表达式验证域名
python·mysql·正则表达式
java小吕布1 小时前
Java中的排序算法:探索与比较
java·后端·算法·排序算法
XMYX-01 小时前
Python 操作 Elasticsearch 全指南:从连接到数据查询与处理
python·elasticsearch·jenkins
正义的彬彬侠1 小时前
sklearn.datasets中make_classification函数
人工智能·python·机器学习·分类·sklearn
belldeep1 小时前
python:用 sklearn 转换器处理数据
python·机器学习·sklearn
安静的_显眼包O_o1 小时前
from sklearn.preprocessing import Imputer.处理缺失数据的工具
人工智能·python·sklearn
安静的_显眼包O_o1 小时前
from sklearn.feature_selection import VarianceThreshold.移除低方差的特征来减少数据集中的特征数量
人工智能·python·sklearn
_可乐无糖1 小时前
pytest中的断言
python·pytest
Goboy1 小时前
工欲善其事,必先利其器;小白入门Hadoop必备过程
后端·程序员
Wils0nEdwards1 小时前
Leetcode 整数转罗马数字
linux·python·leetcode