Django框架7
目录
一.多对多的三种创建方式
1.全自动(较为常用)
class Book(models.Model):
title = models.CharFiel(max_length=32)
authors = models.ManyToManyField(to='Author')
# orm就会自动帮你创建第三张表
class Author(models.Model):
name = models.CharField(max_length=32)
# 好处是:第三张表自动创建
# 不足之处是:第三张表无法扩展额外的字段
2.纯手动(了解)
class Book(models.Model):
title = models.CharFiel(max_length=32)
class Author(models.Model):
name = models.CharField(max_length=32)
class Book2Author(models.Model):
book = models.ForeignKey(to='Book')
author = models.ForeignKey(to='Book')
create_time = models.DateField(auto_now_add=True)
# 好处是在于第三张表可以扩展额外的字段
# 不足之处:没有了正反向查询,orm的查询会带来不便
3.半自动(推荐)
外键字段加在Book里
class Book(models.Model):
title = models.CharField(max_length=32)
authors = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('book', 'author'))
class Author(models.Model):
name = models.CharField(max_length=32)
class Book2Author(models.Model):
book = models.ForeignKey(to='Book')
author = models.ForeignKey(to='Author')
create_time = models.DateField(autu_now_add=True)
外键字段加在Author里
class Book(models.Model):
title = models.CharField(max_length=32)
class Author(models.Model):
name = models.CharField(max_length=32)
books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=('author', 'book'))
class Book2Author(models.Model):
book = models.ForeignKey(to='Book')
author = models.ForeignKey(to='Author')
create_time = models.DateField(autu_now_add=True)
# 好处在于第三张表可以扩展任意的额外的字段,还可以利用orm进行正反向查询
# 不足之处在于:没有了add,set,remove,clear这些方法
# 但是可以直接操作数据库
二.Ajax
同步与异步:
同步:任务提交之后原地等待任务的返回结果 进程表现来说 阻塞
异步: 任务提交之后不需要原地等待返回结果 直接执行下一行代码
进程表现为 非阻塞
任务的结果是通过异步回调机制 callback()
Ajax:
异步提交 局部刷新
与后端进行交互的方式
1.浏览器窗口输入url回车 GET
2.a标签href属性填写url点击 GET
3.form表单 GET/POST
4.Ajax GET/POST
Ajax并不是一门新的语言,它就是基于js写的一个功能模块
ajax基本的语法结构
$.ajax({
1.朝那个后端提交数据
url:"", 控制数据的提交方式 有三种写法 跟form表单的action属性一致
2.指定当前的请求方式
type:'post',
3.提交的数据
data:{
'i1': $('#i1').val(),
'i2': $('#i2').val()
}
4.ajax是异步提交,所以需要给一个回调函数来处理返回的结果
success:function(data){
data就是异步提交返回的结果
将异步回调的结果通过DOM操作渲染到第三个input框中
$('#i3').val(data)
}
})
为一个按钮添加绑定事件
<script>
$('#d1').click(function () {
})
</script>
script也是写在body里的
后端代码
from django.shortcuts import render, HttpResponse
# Create your views here.
def index(request):
if request.method == 'POST':
i1 = request.POST.get('i1')
i2 = request.POST.get('i2')
i3 = int(i1) + int(i2)
return HttpResponse(i3)
return render(request, 'index.html')
三.content-type前后端传输数据编码的格式
主要有三种:
urlencoded
formdata
application/json
form表单
默认是urlencoded编码格式传输数据
urlencoded数据格式
username = jason&password=123
django后端针对该格式的数据,会自动解析并帮你打包到request.POST中
formdata数据格式
django后端针对符合urlencoded编码格式数据(普通键值对)还是统一解析到request.POST中
而针对formdata文件数据就会自动解析到request.FILES中
ajax提交
1.ajax默认的也是urlencoed编码格式
前后端数据交互 编码格式与数据格式一定要保持一致
四.Ajax发送json数据格式
django后端针对jason格式数据 并不会做任何的处理
而是直接放在request.body中
前端代码
<script>
$('#d2').on('click',function(){
$.ajax({
url: '',
type: 'post',
contentType:'application/json',
data:JSON.stringify({'username': 'jason', 'password': 123}),
success:function(data){
alert(data)
}
})
})
</script>
后端代码
def ab_ct(request):
if request.method == 'POST':
# # 自己来处理数据格式
json_bytes = request.body
# # 先解码
# json_str = json_bytes.decode('utf-8')
# # 再反序列化
# json_dict = json.loads(json_str)
# 这里json.loads能够自动解码并序列化
json_dict = json.loads(json_bytes)
print(json_dict)
return render(request, 'ab_ct.html')
五.Ajax发送文件数据
内置对象 FormData
即发普通键值对也发文件
前端代码
ajax发送文件数据需要借助内置对象
<script>
$('#d3').click(function(){
1.需要生成一个内置对象
var myFormData = new FormData();
2.传普通键值对 当普通键值对较多的时候 我们可以利用for循环来添加
myFormData.append('username', 'jason');
myFormData.append('password', 123);
})
3.传文件
myFormData.append('myfile', $( '#i3')[0].files[0]);
发送ajax请求
$.ajax({
url: '',
type: 'post',
data: myFormData,
发送formdata对象需要指定两个关键性参数
processData:false, 让浏览器不需要对你的数据进行任何操作
contentType:false, 不要使用任何的编码格式 对象formdata自带编码格式,并且django能够识别该对象
success: function(data){
alert(data)
}
})
</script>
后端
request.POST接收字典普通键值对
request.FILES接收文件对象
六.django内置的序列化功能
前后端数据交互的情况下都是一个大字典
接口档案 表明该大西点内部都有哪些键值对
from app01 import models
from django.core import serializers
def ab_se(request):
user_queryset = models.Userinfo.objects.all()
res = serializes.serialize('json', user_queryset)
return HttpResponse(res)
七.Ajax结合sweetalert实现删除二次确认
后端代码
from django.http import JsonResponse
import time
def show_user(request):
"""
前后端如果是通过ajax进行交互 那么交互的媒介一般情况下都是一个字典
:param request:
:return:
"""
if request.method == 'POST':
time.sleep(3)
back_dic = {"code":1000,'msg':''}
delete_id = request.POST.get('delete_id')
models.Userinfo.objects.filter(pk=delete_id).delete()
back_dic['msg'] = '删除成功,准备跑路!!!'
return JsonResponse(back_dic)
user_queryset = models.Userinfo.objects.all()
return render(request,'show_user.html',locals())
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
{% load static %}
<link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}">
<script src="{% static 'dist/sweetalert.min.js' %}"></script>
<style>
div.sweet-alert h2 {
padding-top: 10px;
}
</style>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h2 class="text-center">数据展示</h2>
<table class="table-hover table table-striped">
<thead>
<tr>
<th>主键</th>
<th>用户名</th>
<th>密码</th>
<th>性别</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for user_obj in user_queryset %}
<tr>
<td>{{ user_obj.pk }}</td>
<td>{{ user_obj.username }}</td>
<td>{{ user_obj.password }}</td>
<td>{{ user_obj.get_gender_display }}</td>
<td>
<a href="#" class="btn btn-primary btn-xs">编辑</a>
<a href="#" class="btn btn-danger btn-xs cancel" data_id="{{ user_obj.pk }}">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<script>
$('.cancel').click(function () {
var $aEle = $(this);
swal({
title: "你确定要删吗?",
text: "你如果删了,你可要准备跑路啊!",
type: "warning",
showCancelButton: true,
confirmButtonClass: "btn-danger",
confirmButtonText: "是的,老子就要删!",
cancelButtonText: "惹不起惹不起!",
closeOnConfirm: false,
closeOnCancel: false,
showLoaderOnConfirm: true
},
function (isConfirm) {
if (isConfirm) {
// 发送ajax请求
$.ajax({
url:'',
type:'post',
data:{'delete_id':$aEle.attr("data_id")},
success:function (data) { // 回调函数会自动将二进制的json格式数据 解码并反序列成js中的数据类型
if (data.code == 1000){
swal("删了!", "你准备跑路吧!", "success");
// 方式1
{#window.location.reload()#}
// 方式2 DOM操作动态修改
$aEle.parent().parent().remove() // 将标签直接移除
}else{
swal('发生了未知的错误', "error");
}
}
});
} else {
swal("怂笔", "你成功的刷新我对你的认知", "error");
}
});
})
</script>
</body>
</html>
八.批量插入数据
def ab_bc(request):
book_list = []
for i in range(1, 10001):
book_list.append(models.Book(title='新的%s书'%i))
models.Book.objects.bulk_create(book_list)
book_queryset = models.Book.objects.all()
return render(request, 'ab_bc.html', locals())
九.自定义分页器(主要理解里面的编程思想思路)
后端代码
current_page = request.GET.get('page', 1)
all_count = book_queryset.count()
page_obj = Pagination(current_page=current_page, all_count-all_count, pager_count=9 )
page_queryset = book_queryset[page_obj.start:page_obj.end]
return render(request, 'ab_bc.html', locals())
前端代码
{% for book_obj in page_queryset %}
<p>
{{book_obj,title}}
</p>
{% endfor %}
{{ page_pbj.page_html|safe }}