最新要闻

广告

手机

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

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

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

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

家电

世界新消息丨django10 分页器与Form组件

来源:博客园


(相关资料图)

多对多创建第三张表的三种方式

# 1.全自动创建#  优势:自动创建第三张表,并且提供了add,remove,set,clear四种操作与正反向查询#  劣势:第三张表无法创建更多的字段,扩展性很差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)# 2.纯手动创建#  优势:第三张表的扩展性强#  劣势: 编写麻烦,手动录入的字段多,不再支持add,remove,set,clear以及正反向查询class Book(models.Model):    title = models.CharField(max_length=32)class Author(models.Model):    name = models.CharField(max_length=32)class Book_Author(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)# 3.半自动创建#  优势: 第三张表由自己创建,扩展性强,正反向查询依旧可用#  劣势: 编写麻烦,不支持add,remove,set,clearclass Book(models.Model):    title = models.CharField(max_length=32)    authors = models.ManyToManyField(to="Author", through="Book_Author", through_field=("book","author"))        class Author(models.Model):    name = models.CharField(max_length=32)    class Book_Author(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)

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

"""前后端分离的项目,视图函数只需要返回json格式的数据即可"""from app01 import modelsfrom django.http import JsonResponsedef ab_ser_func():    # 1.查询所有的书记对象    book_queryset = models.Book.objects.all() # # queryset [对象、对象]    # 2.封装成大字典返回   {{"pk":"","title":"",{},{}"}}    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)"""前端查后端的接口的网站   : bejson.com"""# django的序列化组件
# 1.导入内置的序列化模块from django.core import serializers# 2.调用该模块下的方法,第一个参数是你想以什么样方式来序列化数据res = serializers.serialize("json", book_queryset)return HttpResponse(res)

orm批量操作数据

模型层:    class Books(models.Model):        title = models.CharField(max_length=32)# 1.普通循环插入数据  - 前端:            {% for book_obj in book_questset %}            

{{ book_obj.title }}

{% endfor %} - 后端: def ab_bk_func(request): # 1.往books表中插入了10万条数据 """直接循环插入的话需要10s才能插入500条左右的数据""" for i in range(1,100000): models.Books.objects.create(title="第%s本书" % i) # 2.查询所有的表中并展示到前端页面 book_queryset = models.Books.objects.all() return render(request,"BkPage.html",locals())# 2.使用orm语句操作批量插入 - 前端 {% for book_obj in book_questset %}

{{ book_obj.title }}

{% endfor %} - 后端 """使用orm进行批量插入的的话5s左右就可以将10万条数据插入完毕""" book_obj_list = [] # 可以用列表生成式[... for i in ... if ...] 生成器表达式(... for i in ... if ...) for i in range(1,100000): # 类名加括号产生对象 book_obj = models.Books(title="第%s本书" % i) book_obj_list.append(book_obj) # 批量插入数据 models.Books.objects.bulk_create(book_obj_list) book_queryset = models.Books.objects.all() return render(request,"BkPage.html",locals())

分页器

# 为何要存在分页器?"""推导过程"""   - 1.queryset支持切片操作(正数)   - 2.研究各个参数之间的数学关系          每页固定展示多少条数据、起始位置、终止位置   - 3.自定义页码参数          current_page = request.GET.get("page")   - 4.前端展示分页器样式   - 5.总页码数问题          divmod方法   - 6.前端页面页码个数渲染问题          后端产生,前端渲染
# 推导流程def index(request):book_data = models.Book.objects.all()# 计算一共的数据条数all_count = book_data.count()# 2.自定义每一页展示的数据条数per_page_num = 10# 获取总页数all_page_num,more =divmod(all_count,per_page_num)if more:    all_page_num += 1# 1.获取前端想要展示的页码,获取用户指定的配置,如果没有配置就默认展示第一页current_page = request.GET.get("page", 1)try:  # 由于后端接受到的前端数据是字符串类型所以我们这里做类型转换处理加异常捕获    current_page = int(current_page)except Exception as e:    current_page = 1html_page =""for i in range(current_page - 5, current_page + 6):    html_page += "
  • %s
  • " % (i, i)# # 3.定义切片的起始位置# start_num = 0# # 4.定义切片的中止位置# end_num = 10start_num = (current_page - 1) * per_page_numend_num = current_page * per_page_numbook_query = models.Book.objects.all()return render(request,"book_list.html", locals())"""current_page、per_page_num、start_page、end_page四个参数之间的数据关系。当per_page_num = 10current_page start_page end_page 1 0 10 2 10 20 3 20 30 4 30 40per_page_num = 5current_page start_page end_page 1 0 5 2 5 10 3 10 15 4 15 20可以很明显的看出规律start_page = (current_page - 1) * per_page_numend_page = current_page* per_page_num"""- 1.QuerySet切片操作- 2.分页样式添加- 3.页码展示(divmod)- 4.渲染所有的页码标签"""前端模板语法虽然不支持range,但是我们可以通过后端创建好html标签传递给html页面使用"""

    自定义分页器的使用

    # 1.django会自带分页器模块但是使用起来麻烦,所以我们自己封装了一个只需要掌握使用的方法
    - 将代码单独放入一个文件夹,当作一个模块导入使用
    class Pagination(object):    def __init__(self, current_page, all_count, per_page_num=2, pager_count=11):        """        封装分页相关数据        :param current_page: 当前页        :param all_count:    数据库中的数据总条数        :param per_page_num: 每页显示的数据条数        :param pager_count:  最多显示的页码个数        """        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("""                                                """)        return "".join(page_html_list)
    - 后端代码: # 导入自定义模块     from app01.plugins import mypage     def index(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]     return render(request,"booklist.html",locals())- 前端代码:      
    {% for book in page_queryset %}

    {{ book.title }}

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

    form组件

    # 1.form组件支持提前设置各种检验规则,之后自动校验# 2.form组件可以支持直接渲染用户数据的各种标签# 3.form组件支持针对不同的校验失败展示不同的提示# 4.form组件的使用- 1. 创建form类型  from django import forms  class MyForm(forms.Form):      name = forms.CharField(max_length=8, min_length=3)  # 用户名最长八个字符 最短三个字符      age = forms.IntegerField(max_value=150, min_value=0)  # 年龄最小0岁 最大150岁      email = forms.EmailField()  # 邮箱必须符合邮箱格式(至少有个@符号)- 2. 数据校验功能    # 1.传递待校验的数据    form_obj = views.MyForm({"name":"jason","age":18,"email":123})    # 2.判断所有的数据是否符合校验    form_obj.is_valid()    # 3.获取符合校验规则的数据    form_obj.cleaned_data    {"name": "jason", "age": 18}    # 4.查阅不符合校验规则的数据及错误原因    form_obj.errors    {"email": ["Enter a valid email address."]}"""1.form类中编写的字段默认都是必填的,少传则肯定通不过校验 is_valid2.校验如果多传了一些字段 则不参与校验 全程忽略"""- 3. 渲染标签功能    # 1.方式1(封装程度高 扩展性差)    {{ form_obj.as_p }}    {{ form_obj.as_table }}    {{ form_obj.as_ul }}    # 2.方式2(封装程度低 扩展性好 编写困难)    {{ form_obj.name.lable }}    {{ form_obj.name }}    # 3.方式3(推荐使用)    {% for form in form_obj %}    

    {{ form.label }}{{ form }}

    {% endfor %} """ 类中以外的所有标签都不会自动渲染 需要自己编写 """- 4. 展示提示信息 -1.form表单如何取消浏览器自动添加的数据校验功能前端:
    {% for form in form_obj %}

    {{ form.label }}{{ form }} {{ form.errors.0 }}

    {% endfor %} 后端: def func(request): form_obj = MyForm() if request.method == "POST": form_obj = MyForm(request.POST) if form_obj.is_valid(): print(form_obj.cleaned_data) return render(request,"func.html",locals())- 5. 一些重要的字段参数 max_length、min_length max_value、min_value label 字段注释 error_messages 错误提示 required 否为空 widget 标签类型、标签属性 initial 默认值 validators 正则校验

    关键词: 起始位置 字符串类型