day57 choise字段与ajax
一。choice字段。
在django的orm中,创建如同性别,民。族等可选择的字段时,可以选择使用choice字段进行定义。
这样的定义可以使用简单的数字代替数据量大的字符,减少数据库的负担。
choice字段没有具体的关键字,而是在某个字段中设置choices值。
class User(models.Model):
username = models.CharField(max_length=32)
age = models.IntegerField()
choices = (
(1,'男'),(2,'女'),(3,'其他')
)
gender = models.IntegerField(choices=choices)
choice是元组套元组的形式,前面的是输入的值和数据库中存储的值,后面的是获取时需要转换的值。
存choice里面罗列的数字与中文对应使用user_obj.get_gender_display()方法,
只要是choices字段 在获取数字对应的注释 固定语法 get_choices字段名_display()
存没有罗列迟来的数字不会报错 还是展示数字。
二。MTV和MVC模式。
在django中,是MTV框架。
1.M:models 模型
2.T:templates 模板
3.V:view 视图
而再其他框架中,也被称之为MVC,也就是:
1.M:models 模型
2.V:view 视图
3.C:controller 控制器
三。ajax
AJAX就是(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”。
也就是说ajax的特点是‘异步提交,局部刷新’,是一个强大的功能。
请求方式可以使用get方式,也可以使用post方法。
除了ajax之外,以下方式也可以使用get和post方法。
1.a标签href, 是get请求。
2.浏览器输入url,get请求。
3.form表单, 可以使用get和post。
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
这一特点给用户的感受是在不知不觉中完成请求和响应过程。
小例子:
$('#b1').on('click',function () {
{#alert(123)#}
// 点击按钮 朝后端发送post请求
$.ajax({
url:'', // 控制发送给谁 不写就是朝当前地址提交
type:'post', // 发送方式是post请求
data:{'i1':$('#i1').val(),'i2':$('#i2').val()}, // 发送的数据
success:function (data) { // data形参用来接收异步提交的结果
{#alert(data)#}
// 将后端计算好的结果 通过DOM操作 渲染到第三个input矿中
$('#i3').val(data)
}
})
})
模板层
def test(request):
if request.is_ajax():
if request.method == 'POST':
d1 = request.POST.get('d1')
d2 = request.POST.get('d2')
ret = int(d1)+int(d2)
return HttpResponse(ret)
return render(request,'test.html')
视图层
四。contentType前后端传输数据编码的格式。
前后端传输数据编码格式有:
1.urlencoded
2.formdata
3.json
1.form表单
在表单中,使用的编码格式默认是urlencoded
数据的格式就是使用&符风格:name=lzx&pwd=123
(1)而,django后端针对urlencoded编码格式的数据会自动解析并放到request.POST中供用户获取。(post格式)
(2)在form中可以修改参数enctype,如果设置成multipart/form-data",就可以接受文件格式的数据。在这个设定下,原来符合urlencoded编码格式的数据也会被服务端自动解析放入request.POST中。而如果是文件格式的数据,就会放入request.FILES中。
如果没有设置multipart/form-data",则会将该文件的文件名放入post中。
2.ajax提交数据。
在ajax中,提交数据的默认方式也是urlencoded,如果指定其中的参数contentType指定了什么类型的数据,客户端就会接受什么数据。
如果数据格式不对,那么服务端就不会处理该数据。
使用ajax发送json数据时,既不会放到POST中也不会放到FILES中,会原封不动的放入request.body中,这种数据就是普通的二进制加被json后的数据。
(contentType:‘application/json’,,设置发送json格式数据)
ajax格式:
$('#b1').on('click',function () {
$.ajax({
url:'', // 控制发送给谁 不写就是朝当前地址提交
type:'post', // 发送方式是post请求
data:JSON.stringify(
{'username':'jason','password':123}
), // 发送的数据
contentType:'application/json',
// 告诉后端你这次的数据是json格式
success:function (data) {
// data形参用来接收异步提交的结果,操作数据
}
})
3.ajax格式传文件。
在form表单中传输文件,只需要设置entype即可将文件添加到POST中。而ajax格式传输文件到POST需要使用一个对象:formData。
$('#b1').on('click',function () {
// ajax传输文件 建议使用内置对象formdata
var formData = new FormData(); // 既可以传普通的键值对 也可以传文件
// 添加普通键值
formData.append('username','jason');
formData.append('password','');
// 传文件
// 如何获取文件标签所存储的文件对象? 固定语法
// 1.先用jQery查找到存储文件的input标签
// 2.将jQuery对象转成原生js对象
// 3.利用原生js对象的方法 .files[0]获取到标签内部存储的文件对象
// 4.一定要指定两个参数都为false
formData.append('my_file',$('#d1')[0].files[0]);
$.ajax({
url:'', // 控制发送给谁 不写就是朝当前地址提交
type:'post', // 发送方式是post请求
data:formData, // 发送的数据
// ajax发送文件需要指定两个额外的参数
processData:false, // 告诉前端不要处理数据
contentType:false, // 不适用任何编码
因为formdata对象自身自带编码 django后端也能够识别formdata对象
success:function (data) {
// data形参用来接收异步提交的结果
}
})
})
其中需要注意的是:
1,formDate对象相当于一个字典,需要想其中append,键值对。而且及支持传输普通数据,又支持传输文件,而且有自带的编码。
2,如何获取input中的文件
1.先使用jquery语句获得$对象,在使用【0】获取原生js对象。最后使用.files【0】取出其中的文件对象。
3.由于formdate对象自带编码格式,所以需要通过代码将编码格式取消:
contentType:false
processData:false
五。序列化组件。
在前后端交互的过程中,django使用对象的方式即可处理数据,也就是对象点属性的方法。而这种对象其他语言识别不了,所以需要将其转化成一种可以让大家都能识别的语言,就需要使用到json格式。
我们可以手动使用for循环将所需要的数据转化成json返回前端。
user_l = []
for user_obj in user_list:
user_l.append(
json.dumps({'username':user_obj.username,
'age':user_obj.age,
'gender':user_obj.get_gender_display()
})
)
这样格式的数据一个网站需要处理很多个,使用django自带了一个序列化的模块:
from django.core import serializers
def reg(request):
user_list = models.User.objects.all()
res = serializers.serialize('json',user_list)
return render(request,'index.html',locals())
其中注意的是第一个需要传入你所需要的类型,第二个参数是queryset对象。最后渲染的结果是:
[{
"model": "app01.user",
"pk": 1,
"fields": {
"username": "jason",
"age": 18,
"gender": 1
}
}, {
"model": "app01.user",
"pk": 2,
"fields": {
"username": "tank",
"age": 24,
"gender": 3
}
}, {
"model": "app01.user",
"pk": 3,
"fields": {
"username": "egon",
"age": 73,
"gender": 2
}
}, {
"model": "app01.user",
"pk": 7,
"fields": {
"username": "kevin",
"age": 29,
"gender": 4
}
}]
渲染结果
六。删除的确认。
在删除数据时,可以设置一个弹窗,将确认这个删除内容,再进行删除操作。
一般的,可以去这个网站上下载点击按钮样式https://lipis.github.io/bootstrap-sweetalert/
使用swal关键字就可以定义删除弹窗
<!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>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
<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-striped table table-hover table-bordered">
<thead>
<tr>
<th>序号</th>
<th>主键</th>
<th>用户名</th>
<th>年龄</th>
<th>性别</th>
<th>操作</th>
</tr>
</thead>
<tbody>
{% for user in user_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ user.pk }}</td>
<td>{{ user.username }}</td>
<td>{{ user.age }}</td>
<td>{{ user.get_gender_display }}</td>
<td>
<button class="btn btn-primary btn-sm">编辑</button>
<button class="btn btn-danger btn-sm del" user_id="{{ user.pk }}">删除</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<script>
$('.del').click(function () {
// 获取当前标签对象
var $btnEle = $(this); swal({
title: "你确定要删吗?",
text: "你要是删了,你就准备跑路吧!",
type: "warning",
showCancelButton: true,
confirmButtonClass: "btn-danger",
confirmButtonText: "是的,老子就要删!",
cancelButtonText: "算了,算了!",
closeOnConfirm: false,
showLoaderOnConfirm: true
},
function(){
// 朝后端发送ajax请求
$.ajax({
url:'',
type:'post',
data:{'delete_id':$btnEle.attr('user_id')},
success:function (data) { // 后端发字典过来 前端不需要你手动转 会自动帮你转换成js自定义对象
if (data.code == 100){
{#window.location.href = ''; // 不写就是条到当前页面#}
// 通过DOM操作 实时改变页面
// 将被点击的删除按钮所在的那一行直接从DOM树中删掉
$btnEle.parent().parent().remove();
swal("删掉了!", "赶紧回去收拾行李吧,准备跑路!", "success");
}else{
swal('发生了未知的错误','估计是有bug了','info')
}
}
}); });
})
</script> </body>
</html>
模板层
from django.http import JsonResponse
import time
def userlist(request):
if request.is_ajax():
time.sleep(3)
"""
一般情况下 针对ajax请求 后端通常都是返回一个字典
"""
back_dic = {'code':100,'msg':''}
# 直接获取用户想删除的数据的id值
delete_id = request.POST.get('delete_id')
# 直接利用queryset方法 批量删除
models.User.objects.filter(pk=delete_id).delete()
# 要给前端ajax返回一个消息(字典)
back_dic['msg'] = '真的删除了!'
return JsonResponse(back_dic)
视图层
注意点:
1.需要在点击按钮上绑定id,为删除的该数据的主键,再使用js拿到该id传给后端。
2.返回的字典需要使用json类型的对象,而json对像在前端可以自动转换,不需要反序列化,直接点操作拿出数据。
3.实时更新的数据可以将删除那一行标签的方法删除。
七。分页器的制作。
对于大量的数据,可以使用以下方法快速创建:bulk_create(l)
1 bulk_create() 批量插入数据
# for i in range(1000):
# models.Book.objects.create(title='第%s本书'%i)
# 上面这种方式 效率极低 l = []
for i in range(10000):
l.append(models.Book(title='第%s本书'%i))
models.Book.objects.bulk_create(l) # 批量插入数据
关于分页器的值作:
def fyq(request):
current_page = request.GET.get('page',1)
current_page = int(current_page)
par_page = 10
start_page = (current_page-1)*par_page
end_page = start_page+par_page
all_book = models.User.objects.all()
# <li><a href="?page=1">1</a></li>
book_count = all_book.count()
page_num,more = divmod(book_count,par_page)
if more:
page_num+=1
html = ''
if current_page<5:
current_page = 5
for i in range(current_page-5,current_page+5):
html+= '<li><a href="?page=%s">%s</a></li>'%(i+1,i+1)
res = models.User.objects.all()[start_page:end_page]
return render(request,'fyq.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>
{% load static %}
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'dist/sweetalert.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
<script src="{% static 'dist/sweetalert.js' %}"></script>
</head>
<body>
{% for i in res %}
<p>{{ i.name }}</p>
{% endfor %}
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{# <li><a href="?page=1">1</a></li>#}
{# <li><a href="?page=2">2</a></li>#}
{# <li><a href="?page=3">3</a></li>#}
{# <li><a href="?page=4">4</a></li>#}
{# <li><a href="?page=5">5</a></li>#}
{{ html|safe }}
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</body>
</html>
模板层
分页器组件:
from app01.utils.mypage import Pagination
def book(request):
book_list = models.Book.objects.all()
current_page = request.GET.get("page",1)
all_count = book_list.count()
page_obj = Pagination(current_page=current_page,all_count=all_count,per_page_num=10)
page_queryset = book_list[page_obj.start:page_obj.end]
试图层
{% for book in page_queryset %}
<p>{{ book.title }}</p>
{% endfor %}
{{ page_obj.page_html|safe }}
模板层
day57 choise字段与ajax的更多相关文章
- 基于ajax提交数据
昨日回顾: 1 inclusion_tag -干什么用的?生成html的片段(动态,传参数,传数据) -app下新建一个模块,templatetags -创建一个py文件(mytag.py) -fro ...
- ajax中的contendType和dataType知识点梳理
在ajax中有2个参数比较重要,之前一直没有搞清楚,下面我们开始梳理一下 1.contentType字段:这个字段的意思,ajax发送给后端的数据是什么类型 如果在ajax中不指定这个属性,则默认是u ...
- backbone学习总结(一)
入职第三天,新公司项目用到backbone+underscore+require等框架,前两天把项目的开发环境都配置好啦,项目也能跑起来,现在准备好好学习公司自己的框架以及用到的框架,有点想吐槽,开发 ...
- Django 的 CSRF 保护机制(转)
add by zhj:假设用户登录了网站A,而在网站B中有一个CSRF攻击标签,点击这个标签就会访问网站A,如果前端数据(包括sessionid)都放在本地存储的话, 当在网站B点击CSRF攻击标签时 ...
- Extjs6(七)——增删查改之删除
本文基于ext-6.0.0 页面就是前面写的那个,有不清楚的可以看一下前面写页面那篇. 一.在toolbar加一个删除按钮 { text:'删除', iconCls:'x-fa fa-times', ...
- 前端校验框架ValidForm之check方法修正
用过validform的朋友相信都知道,在利用check方法的时候,发现该方法对表单输入值只要符合datatype规则的就返回ture.那么我们想对某个字段进行ajax重复校验的时候,只需要在该表单元 ...
- day75
昨日回顾: 1 inclusion_tag -干什么用的?生成html的片段(动态,传参数,传数据) -app下新建一个模块,templatetags -创建一个py文件(mytag.p ...
- Backbone学习总结
Backbone中文学习文档:http://www.css88.com/doc/backbone/ 来到公司已经有一段时间了,到现在深深的感觉到自己的能力弱的像只周黑鸭,又干涩又黝黑,充满了麻(手麻脑 ...
- CVE-2018-7600 Drupal核心远程代码执行漏洞分析
0x01 漏洞介绍 Drupal是一个开源内容管理系统(CMS),全球超过100万个网站(包括政府,电子零售,企业组织,金融机构等)使用.两周前,Drupal安全团队披露了一个非常关键的漏洞,编号CV ...
随机推荐
- flask之请求与响应、闪现(阅后即焚)、请求扩展(before,after)、中间件、LOCAL对象、偏函数、
目录 1.flask请求与响应 2.闪现 3.请求扩展 4.中间件 5.LOCAL对象 6.偏函数 templates 1.flask请求与响应 from flask import Flask,req ...
- JavaScript中一个对象数组按照另一个数组排序
JavaScript中一个对象数组按照另一个数组排序 需求:排序 const arr1 = [33, 11, 55, 22, 66]; const arr2 = [{age: 55}, {age: 2 ...
- 【AtCoder】AtCoder Grand Contest 039 解题报告
点此进入比赛 \(A\):Connection and Disconnection(点此看题面) 大致题意: 给你一个字符串,将它重复\(k\)次.进行尽量少的操作,每次修改一个位置上的字符,使得不存 ...
- python3的ExecJS安装使用
参考官方文档安装 pip3 install PyExecJS 代码编写 import execjs ctx = execjs.compile(""" function a ...
- C#中char[]与string之间的转换;byte[]与string之间的转化
目录 1.char[]与string之间的转换 2.byte[]与string之间的转化 1.char[]与string之间的转换 //string 转换成 Char[] string str=&qu ...
- Kubernetes容器集群 - harbor仓库高可用集群部署说明
之前介绍Harbor私有仓库的安装和使用,这里重点说下Harbor高可用集群方案的部署,目前主要有两种主流的Harbor高可用集群方案:1)双主复制:2)多harbor实例共享后端存储. 一.Harb ...
- 邮件hMailServer +Foxmail 安装使用教程
hMialServer是Windows下一款免费开源的邮件服务器软件,支持smtp.pop3.imap. 本文主要根据官方文档Quick-Start guide整理而成. 一.下载 下载地址:http ...
- Linux less grep
第一步,less查看文件 less 日志文件名 1,这时候,使用组合键 shift + g 可以定位到文件末尾. 在文件末尾,使用组合键(从末尾开始根据之后输入的字符串向上检索) shift + ? ...
- make 命令与 Makefile
make 是一个工具程序,通过读取 Makefile 文件,实现自动化软件构建.虽然现代软件开发中,集成开发环境已经取代了 make,但在 Unix 环境中,make 仍然被广泛用来协助软件开发.ma ...
- C# ICloneable,shallow clone,deep clone.
[Serializable] public class Person:ICloneable { public string Name { get; set; } public int Id { get ...