django修改成ajax分页,Django框架进阶6 多对多三种创建方式, Ajax, Content-Type前后端传输数据编码格式, Ajax发送文件数据, django内置的序列化功能, A...

多对多三种创建方式

1.全自动(较为常用)

class Book(models.Model):

title = models.CharField(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.CharField(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='Author')

create_time = models.DateField(auto_now_add=True)

"""

好处在于第三表可以扩展额外的字段

不足之处:orm查询的时候会带来不便

"""

3.半自动(推荐)

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)

books = models.ManyToManyField(to='Author', through='Book2Author', through_fields=('author', 'book'))

class Book2Author(models.Model):

book = models.ForeignKey(to='Book')

author = models.ForeignKey(to='Author')

create_time = models.DateField(auto_now_add=True)

"""

好处在于第三步可以扩展任意的额外字段 还可以利用orm 正反向查询

不足之处:无法利用

add

set

remove

clear

虽然无法使用了 但是你还可以自己直接操作第三表

"""

Ajax

同步与异步

同步  任务提交之后原地等待任务的返回结果  进程表现上来说  阻塞

异步  任务提交之后不需要原地等待返回结果  直接执行下一行代码  继承表现上来说  非阻塞任务的结果肯定是需要的  是通过异步回调机制  callback()

与后端进行交互的方式

1.浏览器窗口输入url回车    GET

2.a标签href属性填写url点击     GET

3.form表单          GET/POST

4.Ajax            GET/POST

Ajax并不是一门新的语言  它其实就是基于js写的一个功能模块而已

由于原生js书写ajax较为繁琐  所以我们直接学jQuery封装好的ajax模块操作

初识ajax

案例:页面上有三个input框  一个按钮

用户在前两个框中输入数字  点击按钮保证页面不刷新的情况下将数据发到后端做计算

将计算好的结果再发给前端展示到第三个input框中

ajax基本语法结构

// 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)

}

})

例:

995ca0097f18a9e361e84c4d98c7846c.png

templates/index.html

Title

+ =

按钮

$('#d1').click(function () {

// 获取两个框里面内容 朝后端提交异步请求

// 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)

}

})

})

app01/views.py

from django.shortcuts import render,HttpResponse

def index(request):

if request.method == 'POST':

i1 = request.POST.get('i1')

i2 = request.POST.get('i2')

# i1 和 i2 是字符串类型 需要先做类型转换

i3 = int(i1) + int(i2)

return HttpResponse(i3)

return render(request,'index.html')

content-Type前后端传输数据的编码格式

urlencoded

formdata

application/json

form表单

默认是urlencoded编码格式传输数据

31772e0d134d4caea9f736370b7e5551.png

urlencoded数据格式

username=jason&password=123

django后端针对该格式的数据  会自动解析并帮你打包到request.POST中

formdata数据格式

django后端针对符合urlencoded编码格式数据(普通键值对)还是统一解析到request.POST中

而针对formdata文件数据就会自动解析放到request.FILES中

ajax提交

ajax默认的也是urlencoded编码格式

前后端数据交互   编码格式与数据格式一定要一致

application/json

django后端针对json格式数据  并不会做任何的处理

以为没有人拿,所以直接放在request.body中

$('#d2').on('click',function () {

$.ajax({

rl:'',

type:'post',

// 修改content-Type参数

contentType:'application/json',

data:JSON.stringify({'username':'jason','password':123}), // 将数据序列化成json格式字符串

success:function (data) {

alert(data)

}

})

})

例:

templates/ab_ct.html

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

ajax发送json格式数据

$('#d2').on('click',function () {

$.ajax({

url:'',

type:'post',

// 修改content-Type参数

contentType:'application/json',

data:JSON.stringify({'username':'jason','password':123}), // 将数据序列化成JSON格式字符串

success:function (data) {

alert(data)

}

})

})

View Code

app01/views.py

from django.shortcuts import render,HttpResponse

import json

def ab_ct(request):

if request.method == 'POST':

# print(request.POST)

# print(request.FILES)

# print(request.body)

#自己处理json格式数据

json_bytes = request.body

# 先解码

# json_str = json_bytes.decode('utf8')

# 扩展 json.loads能够自动解码并序列化

json_dict = json.loads(json_bytes)

print(json_dict,type(json_dict))

return render(request,'ab_ct.html')

ajax发送文件(******)

内置对象FormData

即发普通键值对也发文件

ajax发送文件数据

$('#d3').click(function () {

// 1 需要先生成一个内置对象

var myFormData = new FormData();

// 2 传普通键值对 当普通键值对较多的时候 我们可以利用for循环来添加

myFormData.append('username','jason');

myFormData.append('password',123);

// 3 传文件

myFormData.append('myfile',$('#i1')[0].files[0]); // 获取input框内部用户上传的文件对象

// 发送ajax请求

$.ajax({

url:'',

type:'post',

data:myFormData,

// 发送formdata对象需要指定两个关键性的参数

processData:false, // 让浏览器不要对你的数据进行任何的操作

contentType:false, // 不要使用任何编码格式 对象formdata自带编码格式并且django能够识别该对象

success:function (data) {

alert(data)

}

})

})

序列化

django内置序列化组件

接口文档 表名该大字典内都有哪些键值对

from django.shortcuts import render,HttpResponse,redirect

import json

# Create your views here.

from app01 import models

from django.core import serializers

def ab_se(request):

user_queryset = models.Userinfo.objects.all()

# user_list = []

# for user_obj in user_queryset:

# user_list.append({

# 'username':user_obj.username,

# 'password':user_obj.password,

# 'gender':user_obj.get_gender_display(),

# })

# res = json.dumps(user_list)

res = serializers.serialize('json',user_queryset) # 注意此处json为字符串

# return render(request,'ab_se.html',locals())

return HttpResponse(res)

其结果为

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

1 [{

2 "model": "app01.userinfo",

3 "pk": 1,

4 "fields": {

5 "username": "jason",

6 "password": "123",

7 "gender": 1

8 }

9 }, {

10 "model": "app01.userinfo",

11 "pk": 2,

12 "fields": {

13 "username": "tank",

14 "password": "234",

15 "gender": 2

16 }

17 }, {

18 "model": "app01.userinfo",

19 "pk": 3,

20 "fields": {

21 "username": "egon",

22 "password": "456",

23 "gender": 3

24 }

25 }, {

26 "model": "app01.userinfo",

27 "pk": 4,

28 "fields": {

29 "username": "sean",

30 "password": "678",

31 "gender": 4

32 }

33 }]

View Code

批量插入

def ab_bc(request):

# 先插入1000条数据

# for i in range(1,1001):

# models.Book.objects.create(title='第%s本书'%i)

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())

自定义分页器

分页器组件

class Pagination(object):

def __init__(self,current_page,all_count,per_page_num=10,pager_count=11):

"""

封装分页相关数据

:param current_page: 当前页

:param all_count: 数据库中的数据总条数

:param per_page_num: 每页显示的数据条数

:param pager_count: 最多显示的页码个数

用法:

queryset = model.objects.all()

page_obj = Pagination(current_page,all_count)

page_data = queryset[page_obj.start:page_obj.end]

获取数据用page_data而不再使用原始的queryset

获取前端分页样式用page_obj.page_html

"""

try:

current_page = int(current_page)

except Exception as e:

current_page = 1

if current_page <1:

current_page = 1

self.current_page = current_page

self.all_count = all_count

self.per_page_num = per_page_num

# 总页码

all_pager, tmp = divmod(all_count, per_page_num)

if tmp:

all_pager += 1

self.all_pager = all_pager

self.pager_count = pager_count

self.pager_count_half = int((pager_count - 1) / 2)

@property

def start(self):

return (self.current_page - 1) * self.per_page_num

@property

def end(self):

return self.current_page * self.per_page_num

def page_html(self):

# 如果总页码 < 11个:

if self.all_pager <= self.pager_count:

pager_start = 1

pager_end = self.all_pager + 1

# 总页码 > 11

else:

# 当前页如果<=页面上最多显示11/2个页码

if self.current_page <= self.pager_count_half:

pager_start = 1

pager_end = self.pager_count + 1

# 当前页大于5

else:

# 页码翻到最后

if (self.current_page + self.pager_count_half) > self.all_pager:

pager_end = self.all_pager + 1

pager_start = self.all_pager - self.pager_count + 1

else:

pager_start = self.current_page - self.pager_count_half

pager_end = self.current_page + self.pager_count_half + 1

page_html_list = []

# 添加前面的nav和ul标签

page_html_list.append('''

''')

first_page = '

首页' % (1)

page_html_list.append(first_page)

if self.current_page <= 1:

prev_page = '

上一页'

else:

prev_page = '

上一页' % (self.current_page - 1,)

page_html_list.append(prev_page)

for i in range(pager_start, pager_end):

if i == self.current_page:

temp = '

%s' % (i, i,)

else:

temp = '

%s' % (i, i,)

page_html_list.append(temp)

if self.current_page >= self.all_pager:

next_page = '

下一页'

else:

next_page = '

下一页' % (self.current_page + 1,)

page_html_list.append(next_page)

last_page = '

尾页' % (self.all_pager,)

page_html_list.append(last_page)

# 尾部添加标签

page_html_list.append('''

''')

return ''.join(page_html_list)

后端代码

current_page = request.GET.get('page', 1) # 当前页数

all_count = book_queryset.count() # 数据总条数

# 1 现生成一个自定义分页器类对象

page_obj = Pagination(current_page=current_page,all_count=all_count,pager_count=9)

# 2 针对真实的queryset数据进行切片操作

page_queryset = book_queryset[page_obj.start:page_obj.end]

return render(request,'ab_bc.html',locals())

前端代码

{% for book_obj in page_queryset %}

{{ book_obj.title }}

{% endfor %}

{{ page_obj.page_html|safe }}

ajax结合sweetalert实现删除二次确认

6b1254a1d9e09742d00439aa5acd15a5.png

代码:

views.py

from app01 import models

from django.http import JsonResponse

import time

def show_user(request):

'''

前后端如果是通过ajax进行交互 那么交互的媒介一般情况下都是一个字典

:param request:

:return:

'''

if request.method == 'POST':

time.sleep(3) # 模拟延迟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())

models.py

from django.db import models

class Userinfo(models.Model):

username = models.CharField(max_length=32)

password = models.CharField(max_length=32)

gender_choices = ((1,'male'),(2,'female'),(3,'other'))

gender = models.IntegerField(choices=gender_choices)

templates/show_user.html

Title

{% load static %}

div.sweet-alert h2{

padding-top: 10px;

}

数据展示

主键用户名密码性别操作

{% for user_obj in user_queryset %}

{{ user_obj.pk }}{{ user_obj.username }}{{ user_obj.password }}{{ user_obj.get_gender_display }}

编辑

删除

{% endfor %}

$('.cancel').click(function () {

var $aEle = $(this); {# 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");

// 方式一 页面刷新

{#window.location.reload() #}

// 方式二 DOM操作动态修改

$aEle.parent().parent().remove()

}else{

swal('发生了未知的错误','error') // 将标签直接移除

}

}

});

} else {

swal("怂逼", "你成功的刷新我对你的认知 :)", "error");

}

});

})

来源:https://www.cnblogs.com/ludingchao/p/12178133.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值