ForeignKey属性
to:设置要关联的表
related_name: 反向操作时,使用的字段名,用于代替原反向查询时的’表名_set’
related_query_name:反向查询操作时,使用的连接前缀,用于替换表名
to_field:设置要关联的表的字段on_delete: OneToOneField, ForeignKey 必须写on_delete,不写报错
models.CASCADE 删除关联数据,与之关联也删除
models.DO_NOTHING :publish_id字段原封不动
models.PROTECT 删除关联数据,引发错误ProtectedError
models.SET_NULL删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)
models.SET_DEFAULT删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)models.SET删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)publish = models.ForeignKey(to='Publish',on_delete=models.SET_NULL,null=True) publish = models.ForeignKey(to='Publish',on_delete=models.SET_DEFAULT,default=1) publish = models.ForeignKey(to='Publish',on_delete=models.DO_NOTHING,db_constraint=False)
db_constraint:公司一般都设置为False
是否在数据库中创建外键约束,默认为True
db_constraint=False 在数据库中不建立外键约束,但是orm查询,继续用
ManyToManyField属性
ManyToManyField 用于表示多对多的关联关系。在数据库中通过第三张表来建立关联关系
to 设置要关联的表,中间是有个中间表的,区别于一对多
related_name 同ForeignKey字段。
related_query_name 同ForeignKey字段。
through:在使用ManyToManyField字段时,Django将自动生成一张表来管理多对多关联关系
也可以手动创建第三张表来管理多对多关系,此时需通过through来指定第三张表的表名
through_fields设置关联的字段。db_table 默认创建第三张表时,数据库中表的名称。
中间表创建方式
1、自动生成:用不到through 和 through_fields
authors=models.ManyToManyField(to='Author',db_table='中间表表名')
2、手动创建中间表,使用through指定
三张表都要手动创建,3个类、3个表模型
# 什么情况会使用手动创建----中间表如果有多的字段,都是手动创建authors=models.ManyToManyField(to='Author',through='booktoauthor', through_fields=('当前表--》到中间表的外键关系','剩下的写在第二个位置'))
# 自动创建中间表,有快捷操作
-add/-remove/ -set/ -clear
手动创建中间表,中间表我们自己能拿到,这些快捷操作,就没了
# 纯手动创建中间表,不使用ManyToManyField关联
不会在book或author表中加 ManyToManyField 字段了
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请求的库# 计算小案例 -编码格式是 :urlencoded
demo.html <body> <input type="text" id="one">+ <input type="text" id="two">= <input type="text" id="three"> <button class="btn">计算</button> <script> $(".btn").click(function (){ var one = $("#one").val(); var two = $("#two").val(); //把获得的值提交到后端 $.ajax({ url:'', type:'post', data:{one:one,two:two}, //接收后端返回的数据 success:function (res){ console.log(res,) if (res.code == 100){ $("#three").val(res.result) }else { alert(res.msg) } } }) }) </script>
view.py from django.shortcuts import render,HttpResponse from django.http import JsonResponse def demo(request): if request.method == 'GET': return render(request,'demo.html') else: one = int(request.POST.get('one')) two = int(request.POST.get('two')) return JsonResponse({'code':100,'msg':'计算成功','result':one+two})
# 上传文件 -编码格式:form-data
demo.html <body> <h1>文件上传</h1> <input type="file" id="id_file"> <button id="id_submit">上传文件</button> <script> $("#id_submit").click(function (){ var formdata = new FormData // $('#id_file')[0].files[0] formdata.append('myfile',$('#id_file')[0].files[0]) //把获得的值提交到后端 $.ajax({ url:'', type:'post', // 指定编码,上传文件 processData: false, //默认会预处理数据,变成,one=1&two=2 contentType:false, //默认是urlencoded,不指定编码,上传文件必须要用from-data data:formdata, //接收后端返回的数据 success:function (res){ console.log(res,) if (res.code == 100){ alert(res.msg) }else { alert(res.msg) } } }) }) </script> </body>
views.py def demo(request): if request.method == 'GET': return render(request,'demo.html') else: # one = int(request.POST.get('one')) # two = int(request.POST.get('two')) myfile=request.FILES.get('myfile') with open(myfile.name,'wb')as f: for line in myfile: f.write(line) return JsonResponse({'code':100,'msg':'上传成功'})
# json格式用的多,后期
$.ajax({ url: '/demo01/', method: 'post', contentType: 'application/json', data: JSON.stringify({name: 'lqz', age: 19}), // 把对象转成字符串形式,json格式字符串 success: function (data) { console.log(data) } })
cookie
# 存在浏览器上的键值对,就是cookie
cookie哪里来的?服务端返回的--》放在响应头的cookie中---》浏览器会自动取出来--》放到cookie中
再次向cookie所在的域发送请求,它会自动携带当时存的cookie
# 存在于服务端的键值对,称之为session
{'11111':{name:lqz},'22222':{name:zs}}
连表的链接方式
数据库表的连接方式:
先总体概述一下:一般用的是join 和 union
1. 笛卡尔积:join
2. 内连接:inner join on
3. 外连接:全外连接full join on,左外连接left join on,右外连接right join on
4. 联合查询:Union 和Union all用于测试的两张表:
两表关联,把左表的列和右表的列通过笛卡尔积的形式表达出来。
select * from t1 join t2
两表关联,保留两表中交集的记录。
select * from t1 inner join t2 on t1.id = t2.id;
两表关联,两表的内容均保留,没有关联的字段用null表示。
oracle里面有full join,但是在mysql中没有full join。我们可以使用union来达到目的。select * from t1 full join t2 on t1.id = t2.id 或 select * from t1 left join t2 on t1.id = t2.id union select * from t1 right join t2 on t1.id = t2.id;
两表关联,左表全部保留,右表关联不上用null表示。
select * from t1 left join t2 on t1.id = t2.id
两表关联,右表全部保留,左表关联不上用null表示。
select * from t1 right join t2 on t1.id = t2.id
用于测试的两张表:
查询两张表中的文章 id 号及标题,并去掉重复记录:
select aid,title from article union select bid,title from blog
查询两张表中的文章 id 号及标题,并返回所有记录:
select aid,title from article union all select bid,title from blog
ajax登录和注册案例
# 注册功能(邮箱和用户名头像)
1、注册使用ajax注册,能够上传头像,上传的头像保存到media文件夹下
2、浏览器中能访问
3、用户名不能重复:ajax,输入框光标失去焦点,就去后端校验用户名是否存在,如果存在,把输入框情况,并弹出alert 说用户名不能重复$('#id_json').blur(function(){ $("#three").val('') alert() })
# 登录功能---》ajax登录
既可以用邮箱登录,又可以用用户名登录