最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

世界速递!框架第九课---ajax补充说明,多对多三种创建方式,django内置序列化组件(drf前身),ORM批量操作数据(ORM操作优化),自定义分页器,form组件

来源:博客园

表相关SQL语句复习

alter table 表名 rename 新表名;           # 修改表名---------------------alter table 表名 add 字段名 字段类型(数字) 约束条件;  # 添加字段名在原来已有的最后一个字段后面再加一个字段!!!---------------------alter table 表名 add 字段名 字段类型(数字) 约束条件 after 已有字段;  # 添加字段名在after后面指定的字段下面添加一个字段!!!---------------------alter table 表名 add 字段名 字段类型(数字) 约束条件 first 已有字段;  # 添加字段名在已有的字段最前面再添加一个字段!!!---------------------alter table 表名 change 旧字段名 新字段名 字段类型(数字) 约束条件;  # 修改字段名change不仅支持修改字段名也支持在在修改字段名的同时也修改字段类型!!!change也支持不修改字段名就修改字段类型,这样新字段名就要与旧字段名写一样了!!!---------------------alter table 表名 drop 字段名;    # 删除字段名每次只能删一个字段!!!删字段要慎重,删一个字段,该字段下的所有数据全没了!!!!!!

昨日内容回顾

  • Q查询进阶操作

    from django.db.models import Qq_obj = Q()q_obj.connector = "or"q_obj.children.append("name",1)q_obj.children.append("price__gt",2000)models.Book.objects.filter(q_obj)目的就是能够把查询条件变成字符串的形式!!!
  • ORM查询优化


    (资料图片仅供参考)

惰性查询、分页处理1.only与deferonly会将括号内填写的字段封装到数据对象中 后续获取不走SQL但是获取括号内没有的字段数据则需要走SQLdefer与only恰巧相反----------------------------------------2.select_related与prefetch_relatedselect_related括号内填写一对多、一对一字段 自动连表然后数据封装到对象res1 = models.Author.objects.select_related("author_detail")-----------------------------------------prefetch_related括号内填写一对多、一对一字段 基于子查询然后数据封装到对象res = models.Book.objects.prefetch_related("publish")这两种方法的封装的对象,样子一样,数据也是一样,在使用的时候,是感觉不出来,用的那种方法的产生的对象的。
  • ORM事务操作

    方式1:配置文件数据库相关配置添加一个键值对    "AUTOMIC_REQUESTS":True方式2:装饰器    from django.db import transaction    @transaction.atomic    def index(request):pass方式3:with上下文管理    with transaction.atomic():            pass
  • ORM常用字段类型

    AutoFieldCharFieldIntegerFieldBigIntegerFieldDecimalFieldEmailFieldDateFieldDateTimeFieldTextFieldBooleanFieldFileField
  • ORM常用字段参数

    primary_keymax_lengthmax_digitsdecimal_placesverbose_namenulldefaultauto_nowauto_now_addchoicesuniquedb_indextoto_fieldon_delete
  • Ajax操作

异步提交 局部刷新--------  我们所学习的是jQuery封装的版本 所以页面上必须要提前导入jQuery资源--------  $.ajax({      url:"",  控制数据提交的地址 有三种填写方式 与form标签action一致      type:"",  控制数据的提交方式 默认也是get      data:{"name":"jason","age":18},  控制提交的数据      success:function(args){          异步回调函数的代码      }  })  使用ajax交互 那么后端返回的数据会被args接收 不再直接影响整个浏览器页面------------
  • 数据编码格式

    1.urlencodedname=jason&age=123&hobby=readrequest.POST\request.GET2.formdatarequest.POST    request.FILES3.application/jsonrequest.body
  • ajax发送json格式数据

1.确保data对应的数据是json格式字符串  data:JSON.stringify({})  2.修改数据编码格式(默认是urlencoded)  contentType:"applicaton/json"
  • ajax携带文件数据
ajax携带文件数据,需要利用js内置函数产生一个对象,然后将相关的数据添加到对象里面去,最后将对象作为一个整体数据给ajax发送给后端!!  let myFormObj = new FormData();  myFormObj.append("name","jason")  myFoemObj.append("myfile",标签对象.files[0])  data:myFormObj  contentType:false     # 不要任何的编码  processData:false     # 不要任何的操作

今日内容概要

  • ajax补充说明
  • 多对多三种创建方式
  • django内置序列化组件(drf前身)
  • ORM批量操作数据(ORM操作优化)
  • 自定义分页器
  • form组件

今日内容详细

ajax补充说明 主要是针对回调函数args接收到的响应数据

-------------------------------------------------------------------1.后端request.is_ajax()用于判断当前请求是否由ajax发出-------------------------------------------------------------------2.后端返回的三板斧都会被args接收不再影响整个浏览器页面-------------------------------------------------------------------3.选择使用ajax做前后端交互的时候 , 后端一般返回的都是字典数据user_dict = {"code": 10000, "username": "小阳人", "hobby": "哎呦喂~"}import jsonuser_data = json.dumps(user_dict)return HttpResponse(user_data)这个时候,前端args接收到的字典已经变成了字符串类型的数据,需要在前端用js代码反序列化,才能拿到真正的字典对象!!!--------------------------------------user_dict = {"code": 10000, "username": "小阳人", "hobby": "哎呦喂~"}from django.http import JsonResponsereturn JsonResponse(user_dict)这个时候JsonResponse会自动将字典序列化,传给ajax,ajax能识别出JsonResponse,会自动将 传来的数据自动再反序列化,就不需要再手动JSON.parse(args) 反序列化了!!!-------------------------------------------------------------------4. ajax自动反序列化后端的json格式的bytes类型数据,需要在ajax代码体里面加一行代码 $.ajax({            url:"",            type:"post",            data:{"name":"jason"},            dataType:"json",           # 加上这行代码就行了!!!            success:function (args) {                console.log(args);                console.log(typeof args)                console.log(args.username)            }这样也能实现自动反序列化的效果!!!-------------------------------------------------------------------

HttpResponse返回,前端args接收到的字典已经变成了字符串类型的数据,需要在前端用js代码反序列化,才能拿到真正的字典对象!!!....

多对多三种创建方式

1.全自动创建class Book(models.Model):        title = models.CharField(max_length=32)        authors = models.ManyToManyField(to="Author")class Author(models.Model):        name = models.CharField(max_length=32)优势:自动创建第三张表 并且提供了add、remove、set、clear四种快捷操作劣势:第三张表无法创建更多的字段 扩展性较差!!!---------------------------------------------------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")        others = models.CharField(max_length=32)        join_time = models.DateField(auto_now_add=True) 优势:第三张表完全由自己创建 扩展性强 劣势:编写繁琐 并且不再支持add、remove、set、clear以及正反向概念-------------------------------------------------------3.半自动创建在外键的括号里面加参数,主动告诉ORM:1. to=                 书与作者有多对多的关系的.2. through=            通过已经建好的第三张表来维护,书与作者多对多的关系.3. through_fields=     用这个第三张表的哪两个外键字段,来维护书与作者的外键关系!!!---------     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", on_delete=models.CASCADE)        author = models.ForeignKey(to="Author", on_delete=models.CASCADE)        others = models.CharField(max_length=32)        join_time = models.DateField(auto_now_add=True)------------------------------优势:第三张表完全由自己创建 扩展性强 正反向概念依然清晰可用劣势:编写繁琐不再支持add、remove、set、clear------------------------------

....

django内置序列化组件(drf前身)

"""前后端分离的项目 视图函数只需要返回json格式的数据即可"""from app01 import modelsfrom django.http import JsonResponsedef ab_ser_func(request):    # 1.查询所有的书籍对象    book_queryset = models.Book.objects.all()  # queryset [对象、对象]    # 2.封装成大字典返回    data_dict = {}    for book_obj in book_queryset:        temp_dict = {}        temp_dict["pk"] = book_obj.pk        temp_dict["title"] = book_obj.title        temp_dict["price"] = book_obj.price        temp_dict["info"] = book_obj.info        data_dict[book_obj.pk] = temp_dict  # {1:{},2:{},3:{},4:{}}    return JsonResponse(data_dict)序列化组件(django自带 后续学更厉害的drf)# 导入内置序列化模块from django.core import serializers# 调用该模块下的方法,第一个参数是你想以什么样的方式序列化你的数据res = serializers.serialize("json", book_queryset)return HttpResponse(res)

....

批量操作数据

def ab_bk_func(request):    # 1.往books表中插入10万条数据    # for i in range(1, 100000):    #     models.Books.objects.create(title="第%s本书" % i)    """直接循环插入 10s 500条左右"""    book_obj_list = []  # 可以用列表生成式[... for i in ... if ...]     生成器表达式(... for i in ... if ...)    for i in range(1, 100000):        book_obj = models.Books01(title="第%s本书" % i)  # 单纯的用类名加括号产生对象        book_obj_list.append(book_obj)    # 批量插入数据    models.Books01.objects.bulk_create(book_obj_list)    """使用orm提供的批量插入操作 5s 10万条左右"""    # 2.查询出所有的表中并展示到前端页面    book_queryset = models.Books01.objects.all()    return render(request, "BkPage.html", locals())

....

分页器思路

分页器主要听处理逻辑 代码最后很简单 推导流程1.queryset支持切片操作(正数)2.研究各个参数之间的数学关系 每页固定展示多少条数据、起始位置、终止位置 3.自定义页码参数    current_page = request.GET.get("page") 4.前端展示分页器样式5.总页码数问题    divmod方法 6.前端页面页码个数渲染问题    后端产生 前端渲染

自定义分页器的使用

django自带分页器模块但是使用起来很麻烦 所以我们自己封装了一个只需要掌握使用方式即可def ab_pg_func(request):    book_queryset = models.Books01.objects.all()    from app01.utils.mypage import Pagination    current_page = request.GET.get("page")    page_obj = Pagination(current_page=current_page, all_count=book_queryset.count())    page_queryset = book_queryset[page_obj.start:page_obj.end]    return render(request, "pgPage.html", locals()){% for book_obj in page_queryset %}   

{{ book_obj.title }}

{% endfor %}{{ page_obj.page_html|safe }}

....

form组件

小需求:获取用户数据并发送给后端校验 后端返回不符合校验规则的提示信息    form组件1.自动校验数据2.自动生成标签3.自动展示信息    from django import formsclass MyForm(forms.Form):    username = forms.CharField(min_length=3, max_length=8)  # username字段最少三个字符最大八个字符    age = forms.IntegerField(min_value=0, max_value=200)  # 年龄最小0 最大200    email = forms.EmailField()  # 必须符合邮箱格式     校验数据的功能(初识) form_obj = views.MyForm({"username":"jason","age":18,"email":"123"})    form_obj.is_valid()  # 1.判断数据是否全部符合要求    False  # 只要有一个不符合结果都是False    form_obj.cleaned_data  # 2.获取符合校验条件的数据    {"username": "jason", "age": 18}    form_obj.errors  # 3.获取不符合校验规则的数据及原因    {"email": ["Enter a valid email address."]}1.只校验类中定义好的字段对应的数据 多传的根本不做任何操作2.默认情况下类中定义好的字段都是必填的

作业

1.整理今日内容及博客2.使用今日内容完善图书管理系统

关键词: 反序列化 字段类型 约束条件