一、前几日内容回顾
对于Queryset内容的理解
print(models.Publish.objects.filter(name='南方出版社'))
print(type(models.Publish.objects.filter(name='南方出版社')))
publish_obj = models.Publish.objects.filter(name='南方出版社').first()
print(publish_obj)
print(type(models.Publish.objects.filter(name='南方出版社').first()))
print(publish_obj.book_set) # app01.Book.None
print(type(publish_obj.book_set))
print(publish_obj.book_set.all()) # 因为一个出版社会有多本书,所以得加all()
for i in publish_obj.book_set.all():
print(i.title)
res = models.Publish.objects.filter(name='南方出版社').values('book__title')
print(res)
for i in publish_obj.book_set.all():
print(i.title)
res = models.Book.objects.select_related('publish')
print(res, type(res))
for obj in res:
print(obj.publish.name)
<QuerySet [<Publish: 出版社对象:南方出版社>]>
<class 'django.db.models.query.QuerySet'>
出版社对象:南方出版社
<class 'app01.models.Publish'>
app01.Book.None
<class 'django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager'>
<QuerySet [<Book: 书籍对象:django从入门到入土爆款>, <Book: 书籍对象:python数据分析爆款>]>
django从入门到入土爆款
python数据分析爆款
<QuerySet [{'book__title': 'django从入门到入土爆款'}, {'book__title': 'python数据分析爆款'}]>
django从入门到入土爆款
python数据分析爆款
<QuerySet [<Book: 书籍对象:python从入门到入土爆款>, <Book: 书籍对象:lunix云计算爆款>, <Book: 书籍对象:django从入门到入土爆款>, <Book: 书籍对象:python数据分析爆款>, <Book: 书籍对象:Golang高并发爆款>]> <class 'django.db.models.query.QuerySet'>
书籍对象:python从入门到入土爆款
北方出版社
书籍对象:lunix云计算爆款
北方出版社
书籍对象:django从入门到入土爆款
南方出版社
书籍对象:python数据分析爆款
南方出版社
书籍对象:Golang高并发爆款
东方出版社
"""
1、个人的理解是通过models.Publish.objects查出来的对象不管后面是value还是all还是filter出来的都是Queryset
2、all还有filter出来的Queryset需要使用first或者for循环取出一个个的class,之后再对class使用.name的方法取到最终的值,all出来的始终都是Queryset套对象!!!!!!!!!!!!!!!!
3、value出来的Queryset里面是一个个的字典,字典也可以使用for之后再使用get方法进行取值
"""
二、总结归纳(具体项目内容放在django12中了)
block content
endblock
{% extends%}
urlpatterns = [
path('admin/', admin.site.urls),
path('bms/', include('app01.urls'))
]
# 注意这里是app01.urls才能将子目录导入
TypeError:‘module‘ object is not iterable
# 这个错误在django中是专门针对url的
thread中可以分为thead和tbody
其中tr是行的意思有几个tr就有几行,并且标题也是占用一行的
{{ book_obj.publish_time|date:'Y年m月d日'}}
搜索浏览器中的过滤器,自动转换为需要的格式
跨表查询
res = models.Book.objects.all()
for obj in res:
print(obj.publish.name)
——————————————————————————————————
反向跨表查询
查询南方出版社出版的书籍
4.1.先拿出版社对象
publish_obj = models.Publish.objects.filter(name='南方出版社').first()
4.2.思考正反向(外键字段在书籍中,所以是反向的)
print(publish_obj.book) # 因为是逆向查询且结果为多个所以要在后面加上_set
print(publish_obj.book_set) # app01.Book.None
print(publish_obj.book_set.all()) # 因为一个出版社会有多本书,所以得加all()
———————————————————————————————————
并表的之后的查询 书多--出版社一
res = models.Book.objects.select_related('publish')
for obj in res:
print(obj.publish.name)
———————————————————————————————————
普通跨表查询
book_obj = models.Book.objects.filter(pk=3).first()
print(book_obj.author) # app01.Author.None
print(book_obj.author.all()) # 因为一本书可以对应多个作者对象,所以得用all()来进行取值
"""
输出的结果为QuerySet套字典
<QuerySet [<Author: 作者对象:jason>, <Author: 作者对象:kevin>]>
"""
———————————————————————————————————
book_queryset = models.Book.objects.select_related('publish')
{% for book_obj in book_queryset %}
b{{ book_obj.author.all }}
基于对象的跨表查询,本来就是基于单个Query对象的
# 首先看出来的是不是单个query对象,如果不是就利用for循环变为单个
# 这里也遵循上面的规律
# html中的魔法方法会自动识别需要加all的东西,并且自动加上,所以不用自己动手加!!!!!!!!!!!!!!!!!!!!!!!!!!
author_list = request.POST.getlist('author_list')
# 注意拿前端的返回值的时候,如果数据为多个,那么必须使用getlist
二、ajax初步使用
异步提交 局部刷新
与form表单的区别可以参考码云网址的注册页手机号输入框
ajax其实就是js自带的功能 不是一门新的技术点 我们学习的是jQuery封装之后版本
普通的提交的方法都是同步提交同步刷新的
<body>
<form action="" method="post">
<input type="text">+<input type="text">=<input type="text">
<input type="submit" value="计算">
</form>
</body>
上面的代码只能是进行提交之后才能进行校验,并且提交之后自动刷新了,原来input框中的内容就没有了
利用abAjax对代码进行改进
<body>
<input type="text" id="d1">+<input type="text" id="d2">=<input type="text" id="d3">
<input type="submit" value="计算" id="subBtn">
<script>
$('#subBtn').click(function () {
$.ajax({
url:'', // 等价于form表单的action参数}
type:'post', // 等价于form表单的method参数}
data:{'i1':$('#d1').val(),'i2':$('#d2').val()}, // 要发送给后端的数据}
success: function (args) { // 形参args就是用于接收后端返回的数据}
$('#d3').val(args)}
})
})
</script>
</body>
————————————————————————————————————————————
def ab_ajax(request):
if request.method == 'POST':
i1 = request.POST.get('i1')
i2 = request.POST.get('i2')
res = int(i1) + int(i2)
return HttpResponse(res)
return render(request,'abAjax.html')
"""
url:'', // 等价于form表单的action参数}
type:'post', // 等价于form表单的method参数}
data:{'i1':$('#d1').val(),'i2':$('#d2').val()}, // 要发送给后端的数据,字典的格式}
success: function (args) { // 形参args就是用于接收后端返回的数据可以利用args给任意标签赋值}
记得复习异步回调以及DOM还有ROM的操作
"""
我们更进一步模仿注册页面
# 即只要光标离开i2就自动进行结果的计算
<body>
<input type="text" id="d1">+<input type="text" id="d2">=<input type="text" id="d3">
<script>
$('#d2').blur(function () {
$.ajax({
url:'', // 等价于form表单的action参数}
type:'post', // 等价于form表单的method参数}
data:{'i1':$('#d1').val(),'i2':$('#d2').val()}, // 要发送给后端的数据}
success: function (args) { // 形参args就是用于接收后端返回的数据}
$('#d3').val(args)}
})
})
</script>
</body>
—————————————————————————————————————————————
def ab_ajax(request):
if request.method == 'POST':
i1 = request.POST.get('i1')
i2 = request.POST.get('i2')
res = int(i1) + int(i2)
return HttpResponse(res)
return render(request,'abAjax.html')
注意事项(is_ajax()停用)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if request.is_ajax():
已经被下面的方法替代了
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
具体理解的步骤详见网页
https://www.ydisp.cn/developer/128266.html
三、ajax详解
1.基础语法
$.ajax({
url:'', 控制数据的提交地址
type:'', 控制请求方式(默认get请求)
data:{}, 组织提交的数据
success:function(形参){
异步回调函数
}
})
2.数据编码格式
Content-Type
格式1:urlencoded
数据格式: name=jason&pwd=123&hobby=read
django后端统一处理到request.POST中
格式2:formdata
数据格式: 无法查阅
django后端自动将文件数据处理到request.FILES 普通数据request.POST
格式3:application/json
数据格式: json格式
django后端不会处理 在request.body中存储(bytes类型) 自己处理
语法注意事项
data: JSON.stringify({'name':'jason','pwd':123}),
contentType:'application/json',
# 因为urlencoded 和formdata 分别是前面讲过的request.POST和request.FILES,下面我们来写request.body
<body>
<button type="submit" id="btn_1" >快点我呀</button>
<script>
$('#btn_1').click(function () {
$.ajax({
url:'',
type:'post',
data: JSON.stringify({'name':'jason', 'pwd':123}),
contentType:'application/json',
success:function (args) {
}
})
})
</script>
</body>
————————————————————————————————————————————————
def ab_ajax(request):
if request.is_ajax():
if request.method == "POST":
print(request.POST)
print(request.FILES)
print(request.body)
return render(request, 'abAjax.html')
3.ajax携带文件数据
<input type="text" id="d1">
<input type="file" id="d2">
<button id="d3">点我</button>
<script>
$('#d3').click(function () {
// 1.产生内置对象
let formData = new FormData();
// 2.添加普通数据
formData.append('username',$('#d1').val())
// 3.添加文件数据
formData.append('file', $('#d2')[0].files[0])
// 4.发送ajax请求
$.ajax({
url:'',
type:'post',
data:formData,
contentType:false, // 不使用任何编码
processData:false, // 不处理数据对象
success:function (args) {
}
})
})
</script>
——————————————————————————————————————————————————
def ab_ajax(request):
if request.is_ajax():
if request.method == "POST":
print(request.POST)
print(request.FILES)
print(request.body)
return render(request, 'abAjax.html')
"""
1.先自己new一个对象,需要传输的数据对着对象进行append就行了
2.$('#d2')[0].files[0] 可以理解为 $('#d2')[0]将jquery对象变为标签对象,之后从标签对象中取文件,如果只有一个文件可以直接使用files[0],如果有多个则可以使用files[0],files[1]进行取用!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3.data中直接写刚才的对象就行了
4.在ajax中设定contentType以及processData为False
"""
4.回调函数
后端跟ajax交互 不应该再返回页面 通常情况下都是返回json格式数据
一般来说使用HttpResponse,render和redirect就不使用了,想要实现redirect的效果只能在前端
<body>
<button type="submit" id="btn_1" >快点我呀</button>
<script>
$('#btn_1').click(function () {
$.ajax({
url:'',
type:'post',
data: '',
success:function (args) {
alert(args)
window.location.href = args
}
})
})
</script>
</body>
——————————————————————————————————————————————
def ab_ajax(request):
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
if request.method == "POST":
return HttpResponse('https://www.baidu.com')
return render(request, 'abAjax.html')
"""
利用BOM操作我们一样可以达到页面重定向的效果
window.location.href = args
"""
5.HttpResponse和JsonResponse
前端针对HttpResponse和JsonResponse返回的json格式数据处理策略不同
前者不会自动反序列化 而后者会自动反序列化
import json
def ab_ajax(request):
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
if request.method == "POST":
return HttpResponse(json.dumps({'name':'jason','pwd':123}))
return render(request, 'abAjax.html')
——————————————————————————————————————————————
<body>
<button type="submit" id="btn_1" >快点我呀</button>
<script>
$('#btn_1').click(function () {
$.ajax({
url:'',
type:'post',
data: '',
success:function (args) {
console.log(typeof args)
console.log(args)
console.log(args.name)
let MyJson = JSON.parse(args)
console.log(MyJson)
console.log(args.name)
}
})
})
</script>
</body>
"""
本来是利用json对数据进行序列化后传输
但是这里console.log(typeof args)的结果却是string,导致args.name是无法进行取值的
JSON.parse(args)反序列化为JS里面的自定义对象
"""
JsonResponse的自动反序列化
<body>
<button type="submit" id="btn_1" >快点我呀</button>
<script>
$('#btn_1').click(function () {
$.ajax({
url:'',
type:'post',
data: '',
success:function (args) {
console.log(typeof args)
console.log(args)
}
})
})
</script>
</body>
————————————————————————————————————————————————
from django.http import JsonResponse
def ab_ajax(request):
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
if request.method == "POST":
return JsonResponse({'name': 'jason', 'pwd': 123})
return render(request, 'abAjax.html')
#如果想让前者也自动反序列化可以添加一个固定的参数dataType:'JSON'
<body>
<button type="submit" id="btn_1" >快点我呀</button>
<script>
$('#btn_1').click(function () {
$.ajax({
url:'',
type:'post',
data: '',
dataType:'JSON'
success:function (args) {
console.log(typeof args)
console.log(args)
console.log(args.name)
}
})
})
</script>
</body>
"""
dataType:'JSON'可以使得不需要再去JsonResponse
在小白必会三板斧中,HttpResponse的作用就是=返回字符串数据,所以其他数据需要进行序列化和反序列化
所以不序列化的返回值类型为string!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
"""
四、SweetAlert弹框插件
官网网址:https://sweetalert.js.org/guides/
使用方式: <script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<a href="#" class="btn btn-danger btn-xs delBtn">删除</a>
{% block js %}
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
<script>
$('.delBtn').click(function (){
swal({
title: "你真的要删除吗?",
text: "如果真的删了你可能需要提桶跑路",
icon: "warning",
buttons: ['取消','确认'],
dangerMode: true,
})
.then((willDelete) => {
if (willDelete) {
swal("牛逼! 数据删了 赶紧跑路!", {
icon: "success",
});
} else {
swal("你个怂货 就知道你不敢!");
}
});
})
</script>
{% endblock %}
"""
这上面就是给按钮绑定删除的弹框
也可以在这里使用ajax进行数据操作
if (willDelete) {下面就可以写上.ajax,之后利用data传输想要删除的id的数据
这里要非常注意<a href="#" class="btn btn-danger btn-xs delBtn">删除</a>
如果写成href=""那么弹框可能只会闪一下!!!!!!!!!!!!!!!!!!!!!!!!
"""
五、序列化
def get_book():
book_query = models.Book.objects.all()
return HttpResponse(book_query)
我们这里想要直接返回所有的书籍数据,但是发现返回的数据不完整
def ser(request):
#拿到用户表里面的所有的用户对象
user_list=models.User.objects.all()
#导入内置序列化模块
from django.core import serializers
#调用该模块下的方法,第一个参数是你想以什么样的方式序列化你的数据
ret=serializers.serialize('json',user_list)
return HttpResponse(ret)
# 上面的代码本质上是替我们干了下面的事
book_query = models.Book.objects.all()
# 将数据全部构造成json格式 {'pk':1,'title':'书'}
book_list = []
for book_obj in book_query:
temp_dict = {}
temp_dict['pk'] = book_obj.pk
temp_dict['title'] = book_obj.title
temp_dict['price'] = book_obj.price
book_list.append(temp_dict)