一。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','123'); // 传文件 // 如何获取文件标签所存储的文件对象? 固定语法 // 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 }}
模板层
最新评论