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) } })
连表的链接方式
数据库表的连接方式:
先总体概述一下:一般用的是join 和 union
1. 笛卡尔积:join
2. 内连接:inner join on
3. 外连接:全外连接full join on,左外连接left join on,右外连接right join on
4. 联合查询:Union 和Union all用于测试的两张表:
1.笛卡尔积 join
两表关联,把左表的列和右表的列通过笛卡尔积的形式表达出来。
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、用户名不能重复,后端校验用户名是否存在,如果存在,把输入框情况,并弹出alert 说用户名不能重复登录功能---》ajax登录,既可以用邮箱登录,又可以用用户名登录
views.py import json from django.shortcuts import render,HttpResponse from django.http import JsonResponse from app01 import models from django.db.models import Q # Create your views here. def login(request): if request.method == 'GET': return render(request,'login.html') else: obj = json.loads(request.body) uemail = obj.get('uemail') password = obj.get('password') print(obj) if uemail and password: user=models.Data.objects.filter((Q(username=uemail) | Q(email=uemail)) & Q(password=password)).first() if user: return JsonResponse({'code': 200, 'url': '/home/'}) else: return JsonResponse({'code': 100, 'msg': '用户名/邮箱或密码错误'}) else: return JsonResponse({'code':101,'msg':'用户名/邮箱或密码未输入'}) def regist(request): if request.method == 'GET': return render(request, 'regist.html') else: obj = json.loads(request.body) username = obj.get('username') email = obj.get('email') password = obj.get('password') if username and password: user=models.Data.objects.filter(username=username).first() if user: return JsonResponse({'code':100,'msg':'用户已存在'}) else: models.Data.objects.create(username=username,email=email,password=password) return JsonResponse({'code':200,'msg':'注册成功','url':'/login/'}) else: return JsonResponse({'code':101,'msg':'用户名或密码未输入'}) def home(request): return render(request,'home.html')
login.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> </head> </head> <body> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } html { height: 100%; } body { height: 100%; } .container { height: 100%; background-image: linear-gradient(to right, #fbc2eb, #a6c1ee); } .login-wrapper { background-color: #fff; width: 358px; height: 588px; border-radius: 15px; padding: 0 50px; position: relative; left: 50%; top: 50%; transform: translate(-50%, -50%); } .header { font-size: 38px; font-weight: bold; text-align: center; line-height: 200px; } .input-item { display: block; width: 100%; margin-bottom: 20px; border: 0; padding: 10px; border-bottom: 1px solid rgb(128, 125, 125); font-size: 15px; outline: none; } .input-item:placeholder { text-transform: uppercase; } .btn { text-align: center; padding: 10px; width: 100%; margin-top: 40px; background-image: linear-gradient(to right, #a6c1ee, #fbc2eb); color: #fff; } .msg { text-align: center; line-height: 88px; } a { text-decoration-line: none; color: #abc1ee; } </style> </head> <body> <div class="container"> <div class="login-wrapper"> <div class="header">登录页面</div> <div class="form-wrapper"> <input type="text" name="username email" placeholder="用户名或邮箱" class="input-item" id="uemail"> <input type="password" name="password" placeholder="密码" class="input-item" id="password"> <div class="btn" id="btn">登录</div> </div> <div class="msg"> 你还没有账号吗? <a href="/regist/">注册</a> </div> </div> </div> </body> <script> $("#btn").click(function () { var uemail = $("#uemail").val(); var password = $("#password").val(); $.ajax({ type:'post', contentType: 'application/json', data:JSON.stringify({uemail,password}), success:function (res){ console.log(res) if (res.code ==200){ location.href = res.url }if (res.code ==100) { alert(res.msg) }else { alert(res.msg) } } }) }) </script> </html>
regist.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> </head> </head> <body> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> * { margin: 0; padding: 0; } html { height: 100%; } body { height: 100%; } .container { height: 100%; background-image: linear-gradient(to right, #fbc2eb, #a6c1ee); } .login-wrapper { background-color: #fff; width: 358px; height: 588px; border-radius: 15px; padding: 0 50px; position: relative; left: 50%; top: 50%; transform: translate(-50%, -50%); } .header { font-size: 38px; font-weight: bold; text-align: center; line-height: 200px; } .input-item { display: block; width: 100%; margin-bottom: 20px; border: 0; padding: 10px; border-bottom: 1px solid rgb(128, 125, 125); font-size: 15px; outline: none; } .input-item:placeholder { text-transform: uppercase; } .btn { text-align: center; padding: 10px; width: 100%; margin-top: 40px; background-image: linear-gradient(to right, #a6c1ee, #fbc2eb); color: #fff; } .msg { text-align: center; line-height: 88px; } a { text-decoration-line: none; color: #abc1ee; } </style> </head> <body> <div class="container"> <div class="login-wrapper"> <div class="header">注册页面</div> <div class="form-wrapper"> <input type="text" name="username" placeholder="用户名" class="input-item" id="username"> <input type="text" name="email" placeholder="邮箱" class="input-item" id="email"> <input type="password" name="password" placeholder="密码" class="input-item" id="password"> <div class="btn" id="btn">注册</div> </div> </div> </div> </body> <script> $("#btn").click(function () { var username = $("#username").val(); var email = $("#email").val(); var password = $("#password").val(); $.ajax({ type:'post', contentType: 'application/json', data:JSON.stringify({username,email,password}), success:function (res){ console.log(res) if (res.code ==200){ alert(res.msg) location.href = res.url }if (res.code ==100) { alert(res.msg) }else { alert(res.msg) } } }) }) </script> </html> </body> </html>
home.html <body> <div class="home"> <div class="content"> <div class="stars"></div> <img class="bgc" src="https://img2.baidu.com/it/u=3722186333,2280425443&fm=253&fmt=auto&app=138&f=JPEG?w=890&h=500" width="70%" alt=""> <h3 class="title">欢迎来到我的个人网站</h3> <h3 class="titles">今天也要加油鸭</h3> </div> </div> </div> </body>