Django-9
当天考试:
1.choices参数的应用场景有哪些,如何获取该字段的值
1、字典值、例如性别、学历、专业、资格证 创建方式: from Django.db import models class user(models.Model): id = AntoFied() gender_choices = ( (1,'male'), (2,'female') ) gender = IntegarField(max_lenght=32) 取值: user_obj = mdelos.user.object.filit(pk = 1).firt() user_obj.get_gender_display()
2.django是什么模型的框架,简述MTV与MVC模型
django自称是MTV模型,实质还是MVC模型 MTV:models templates views MVC: models views controller
3.多对多表关系有几种创建方式,各有什么特点?
有三种 第一种:纯自动 class book(models.Model): title = charField(max_lenght =20 ,verbose_name = '书名') age = IntagerField(verbose_name = '年龄') price = DecimallField(max_digit=10,decimall_places=4) author = ManyToManyField(to='Author') class Author(models.Model): name = CharField(max_lenght=100,verbose = '姓名') “”“ 纯自动特点:好使用; 不足之处:第三张关系表的扩展性极差(没有办法额外添加字段...) 可以通过关键字直接进入第三张表和关联的表,可以使用set,remove,add,clear等方法 ”“” 第二种:半自动 class book(models.Model): title = charField(max_lenght =20 ,verbose_name = '书名') age = IntagerField(verbose_name = '年龄') price = DecimallField(max_digit=10,decimall_places=4) author = ManyToManyField(to='Author', through = 'Book_Author', through_fields = ('book','Author')) class Author(models.Model): name = CharField(max_lenght=100,verbose = '姓名') class Book_Author(models.Model): book = models.Foreignkey('Book') book = models.Foreignkey('Author') """ through_fileds 的先后顺序,通过第三张表查询对应的表 需要用到哪个字段就把哪个字段放前面 你也可以简化判断:当前表是谁就把谁放在前面 优点:可以扩展第三张表字段,可以使用:add,set,remove,clear """ 第三中:纯手动: class Book(models.Model): title = CharField(max_lenght=30) class Author(models.Modle): name = CharField(max_lenght=30) class book_author(models.Model): book = ForeignKey(to='Book') author = ForeignKey(to = 'Author') ''' 优点:第三张表完全取决于你自己进行额外的扩展 不足之处:需要写的代码较多,不能够再使用orm提供的简单的方法 不建议你用该方式 '''
4.什么是ajax,请手写出ajax的基本语法结构及重要参数含义
ajax:是js层面的数据传输方式: jq版本: $.ajax({ url:'', 发送地址 #请求方式 type:'post', #数据 data:JSON.stringify({'name':'js'}), #将返回的数据,自动解析json datatype : 'json', #编码格式 contentType:'appliction/json' })
5、js中json:
编码成json数据 JSON.stringify() 解析 JSON.parse
本日内容:
一、前后端传输数据的编码格式(contentType)
前端from: 默认编码: Content-Type: application/x-www-form-urlencoded 若from 不指定编码,数据传入后端后,文件数据也在post中 可指定编码为mulitpart/from-data 若from 指定编码为:mulitpart/from-data,数据传入后端后,文件数据在FILE中 后端数据存 file_obj = request.FILES.get('file') # 文件对象 print(file_obj.name) with open(file_obj.name,'wb') as f: for line in file_obj.chunks(): # 推荐加上chunks方法 其实跟不加是一样的都是一行行的读取 f.write(line)
二、ajax发送json格式数据:
1、不指定编码格式,会按照“bytes”传输,解码后也只是字符格式
一、不指定编码格式,会按照“bytes”传输,解码后也只是字符格式 $ajax({ url : '', type:'post', data:{"username":'steven','password':'123'} contenType:'application/json' success:function(){ cole.log('123') } }) 二、定编码格式:'application/json',会按照“bytes”传输,解码后也只是字符格式 $('#d4').click(function (){ $.ajax({ url : '', type:'post', contentType: 'application/json', data : JSON.stringify({'name':'wz','password':'123456'}), success:function (args) { console.log(args) } “”“ 注意:contenType: 'application/json' 后,还需要手动转化成json格式, JSON.stringify() 后端需要将数据,解码再转化成json格式 ”“” def index(request): if request.method == 'POST': a = request.body.decode('utf-8') b = json.loads(a) “”“ json.loads(a) 是直接可以将数据先解码,再将json格式数据转化成对应的数据 ”“” return HttpResponse('sb') return render(request,'index.html')
2、判断是否是ajax请求:
def s_web(request): if request.is_ajax(): pass
3、后端向前端发送:
后端发送json数据给前端: 前端解析方式: 1、 a = JSON.parse(args) console.log(a['a']) 2、在ajax加上: datatype = 'JSOM' 后端: def s_web(request): if request.method == 'POST': info = {'a':[2,3,4],'name':'wz'} # return JsonResponse(info) info = json.dumps(info) return HttpResponse(info) “”“ JsonResponse()可以将数据直接转化成json格式 ”“” return render(request,'s_web.html') <script> $('#d4').click(function (){ $.ajax({ url : '', type:'post', dataType:'JSON', contentType: 'application/json', data : {'name':'wz','password':'123456'}, success:function (args) { console.log('sbbbbbb') a = JSON.parse(args) console.log(a['a']) } }) }) </script> “”“ JSON.parse(args) 是将json数据转化成 原来的格式数据 ”“” 二、datatype = 'JSOM':是自动解析后端返回的json数据 “”“ dataType:'JSON'是在jQuery的AJAX请求中设置的一个选项,它指定了服务器返回数据的预期格式。在这种情况下,它告诉jQuery,我们期望从服务器获取JSON格式的数据。 当jQuery接收到来自服务器的响应时,它会根据指定的数据类型(即JSON)将响应数据进行解析。如果响应数据不是JSON格式,则会抛出解析错误。 此外,如果服务器返回的响应数据格式不是预期的JSON格式,这也可能导致解析错误。因此,确保服务器返回的数据格式与dataType指定的类型匹配非常重要,这有助于确保代码的正确性和稳定性。 ”“” <script> $('#d4').click(function (){ $.ajax({ url : '', type:'post', dataType:'JSON', contentType: 'application/json', data : {'name':'wz','password':'123456'}, success:function (args) { a = args console.log(a['a']) } }) }) </script>
三、ajax发送文件数据:
1、前端:
<script> $('#d1').click(function (event){ event.preventDefault() // 点击按钮朝后端发送普通键值对和文件数据 var $from_data_obj = new FormData(); {#fromData: 1、需要先利用FormData内置对象#} //2、FromData 添加数据 $from_data_obj.append('username',$('#v1').val()) $from_data_obj.append('age',$('#v2').val()) $from_data_obj.append('sex',$('#v3').val()) $from_data_obj.append('file1',$('#v4')[0].files[0]) $.ajax({ url : '', type:'post', dataType:'JSON', data : $from_data_obj, // ajax发送文件必须要指定的两个参数 contentType: false, // 不需使用任何编码 django后端能够自动识别formdata对象 processData: false, // 告诉你的浏览器不要对你的数据进行任何处理 success:function (args) { if (args['code'] == 1000){ console.log(args['msg']) } } }) }) </script>
2、后端:
def ab_file(request): if request.is_ajax(): if request.method == 'POST': print(request.POST) print(request.FILES.get('file1')) info = {"code":1000,'msg':''} info['msg'] = '数据已经删了,你赶紧跑路!' # return JsonResponse(info) info = json.dumps(info) # # print(info) return HttpResponse(info) return render(request,'ab_file.html')
3、总结:
1、from:中数据如果给ajax处理,必须阻止后续事件,event.preventDefault() 2、另外数据要一起给后端,并且普通数据在post里面,文件是在FILES,需要用到js内置函数 FromData() 3、用到FromData(),必须指定contentType: false, // 不需使用任何编码 django后端能够自动识别formdata对象,processData: false, // 告诉你的浏览器不要对你的数据进行任何处理 4、
四、ajax结合sweetalert实现删除按钮的二次确认:
1、前端:
<script> $(document).on('click','.delete-btn',function (event) { event.preventDefault(); //阻止默认点击提交行为 {#获取本行最父级标签#} var $del_parents = $(this).parent().parent() console.log($del_parents) {#获取标签的href值#} var $url = $(this).attr('href'); // 获取删除链接 // 使用 SweetAlert2 插件显示一个确认对话框 swal({ title: "Are you sure?", text: "Your will not be able to recover this imaginary file!", type: "warning", showCancelButton: true, confirmButtonClass: "btn-danger", confirmButtonText: "Yes, delete it!", closeOnConfirm: false }, function(){ $.ajax({ url: $url, type: 'GET', dataType:'json', data: {}, success: function (data){ // 删除成功后,弹出删除成功的提示框 swal({ title: "Deleted!", text: "Your imaginary file has been deleted.", type: "success" }, function (){ {#删除这一行#} $del_parents.remove(); }); }, erro: function (xhr, status, error){ {#异常处理#} swal({ title: "Error", text: "An error occurred while deleting the book.", type: "error" }); } }) }); } ) </script>
2、后端:
def delect_book(request,del_id): print(del_id) models.Book.objects.filter(pk=del_id).delete() return JsonResponse({'success': True})
五、django自带的序列化组件(drf做铺垫)
1、前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> {% for user_obj in user_queryset %} <p>{{ user_obj }}</p> {% endfor %} </body> </html>
2、后端:
from django.core import serializers """ serializers.serialize('json',user_queryset)可以批量的将数据通过列表套字典的形式传过去 """ def ab_ser(request): user_queryset = models.User.objects.all() user_queryset = serializers.serialize('json',user_queryset) return HttpResponse(user_queryset) """ 前端展示结果:展示哪张表、主键id、数据 [{"model": "app01.user", "pk": 1, "fields": {"username": "zs1", "age": 34, "gender": 1}}, {"model": "app01.user", "pk": 2, "fields": {"username": "zs2", "age": 32, "gender": 2}}, {"model": "app01.user", "pk": 3, "fields": {"username": "zs3", "age": 13, "gender": 2}}, {"model": "app01.user", "pk": 4, "fields": {"username": "zs4", "age": 23, "gender": 2}}, {"model": "app01.user", "pk": 5, "fields": {"username": "zs5", "age": 4, "gender": 2}}] """
六、批量插入
def ab_pl(request): # 先给Book插入一万条数据 # for i in range(10000): # models.Book.objects.create(title='第%s本书'%i) # # 再将所有的数据查询并展示到前端页面 book_queryset = models.Book.objects.all() # 批量插入 # book_list = [] # for i in range(100000): # book_obj = models.Book(title='第%s本书'%i) # book_list.append(book_obj) # models.Book.objects.bulk_create(book_list) """ 当你想要批量插入数据的时候 使用orm给你提供的bulk_create能够大大的减少操作时间 :param request: :return: """ return render(request,'ab_pl.html',locals())
七、自己写一个分页器(只需要掌握分页器的推导思路即可)
1、前端:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> {% for foo in book_queryset %} <p>{{ foo.title }}</p> {% endfor %} <nav aria-label="Page navigation"> <ul class="pagination"> <li> <a href="#" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> {{ page_html|safe }} <li> <a href="#" aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> </body> </html>
2、后端:
def ab_pl(request): # 3、分页器 book_list = models.Book.objects.all() # 获取想去的某一页 current_page = request.GET.get('page',1)# 如果获取不到当前页码 就展示第一页 # 数据转化 try: current_page = int(current_page) except Exception: current_page = 1 # 每页展示多少条 per_page_num = 10 # 开始位置、、 start_page= (current_page - 1) *10 # 结束位置 end_page= current_page * per_page_num # 计算出需要多少页 all_book = book_list.count() page_num,more = divmod(all_book,per_page_num) if more: page_num += 1 page_html = '' xxx = current_page if current_page < 6: current_page = 6 for i in range(current_page -5,current_page+6): if xxx == i: page_html += '<li class="active"><a href="?page=%s">%s</a></li>'%(i,i) else: page_html += '<li><a href="?page=%s">%s</a></li>'%(i,i) book_queryset = book_list[start_page:end_page] return render(request,'ab_pl.html',locals())
浙公网安备 33010602011771号