• Django paginator and Form


    django  提供的分页器

    django 官方链接: https://docs.djangoproject.com/en/1.11/topics/pagination/

    django提供了一些类来帮助实现分页

    导入这些类

    from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger

    主要使用两个类
    • Paginator objects
    • Page objects

    Paginator objects

    requried argument

    1. object_list
    2. per_page
    object_list

      可以是列表,元组,QuerySet 对象,或者有count() 或__len__()方法的可切片对象,对于一致性的pagination,QuerySets应该被排序,使用order_by() 方法 或者在models设置默认ordering

        A list, tuple, QuerySet, or other sliceable object with a count() or __len__() method. For consistent pagination, QuerySets should be ordered, e.g. with an order_by() clause or with a default ordering on the model.

    per_page

    在一页上item最大的number

    比如在一页想放20个数据,应该设置为20

    可选参数 orphans,                

    when the last page item is less than or equal to orphans ,the last page's item would be added the previous page

    比如有23个item  ,each page have 10 item ,if orphans=3,it will be two pages,not 3 pages.

    by default,orphans=0,

    可选参数  allow_empty_first_page

    是否允许第一页能为空,默认是allow_empty_first_page=True

    如果设置为False ,and object_list is empty ,EmptyPage error will be raised

    Paginator对象的Method  

    Paginator.page(num)

    return Page object with based-on 1 index,if  given page number is not exist ,InvalidPage error will be raised

    Paginator对象的Attributes

    .count

    获得所有页上的所有对象的数量

    .count_pages

    获得页码数

    .page_range

    获得一个基于1的页码迭代器

    例如一共100个对象,每页20个

    .count  返回100

    .count_pages  返回5

    .page_range

    返回[1,2,3,4,5]

    如果页码不是一个整数,会引发 PageNotAnInteger  错误

    Raised when page() is given a valid value but no objects exist on that page.

    当给定的值是有效的,但是在这个页码上不存在objects,会引发EmptyPage  错误

    这连个Expection 都是InvalidPage 的子类

    你可以使用except InvalidPage

    Page objects

    你通常不会手动构建一个Page object ,rather than by Paginator.page()  方法

    当直接迭代它或者使用len() ,page 对象表现得像一个序列

    method

    Page.has_next()

    Page.has_previous()

    Page.has_other_pages()

     Page.next_page_number()

    Page.previous_page_number()

    返回一个整数,这个证书是上一个页码,

    Page.start_index()

    如果有5个对象,每一页有2个对象,对page2使用start_index(),会返回3

    Page.end_index()

    如果有5个对象,每一页有2个对象,对page2使用start_index(),会返回4

    属性attribute

    Page.object_list

    the list of objects on this page

    Page.number

    the page number of this page

    Page.paginator

    the associated Paginator object

     Form

     当我们一个form可能需要几十甚至上百个字段,一些需要提前填充数据,我们可能期待用户在完成操作之前多次编辑提交,还可能需要一些有效性的验证,甚至在表单还没有提交的时候,我们可能需要一些更复杂的字段。

    At this point it’s much easier to get Django to do most of this work for us.

    buliding a form in django   

         the Form class

    forms.py

    from django import forms
    
    class NameForm(forms.Form):
        your_name = forms.CharField(label='Your name', max_length=100)

    一个 form instance 有一个 is_valid() 方法,它会对于所有的字段进行有效性的验证,当这个方法被调用的时候,当所有字段都包含有效性的数据,它将会

    • return True
    • placed the form's data in its cleaned_data attributes

    表单发来的数据我们需要在试图处理它,为了处理表单,我们需要在views实例化它。

    from django.shortcuts import render
    from django.http import HttpResponseRedirect
    
    from .forms import NameForm
    
    def get_name(request):
        # if this is a POST request we need to process the form data
        if request.method == 'POST':
            # create a form instance and populate it with data from the request:
            form = NameForm(request.POST)
            # check whether it's valid:
            if form.is_valid():
                # process the data in form.cleaned_data as required
                # ...
                # redirect to a new URL:
                return HttpResponseRedirect('/thanks/')
    
        # if a GET (or any other method) we'll create a blank form
        else:
            form = NameForm()
    
        return render(request, 'name.html', {'form': form})

    If we arrive at this view with a GET request, it will create an empty form instance and place it in the template context to be rendered.

    This is what we can expect to happen the first time we visit the URL.

    如果得到是get请求,将会创造空的form instance 并被render,  这是我们第一次访问这个URL时所期待发生的

    If the form is submitted using a POST request, the view will once again create a form instance and populate it with data from the request:

     form NameForm(request.POST) This is called “binding data to the form” (it is now a bound form).

    如果是POST请求,view 将会再次创建一个 form instance ,并且从request请求中填充数据,form NameForm(request.POST),被叫做:将数据捆绑到form 上

    We call the form’s is_valid() method; if it’s not True, we go back to the template with the form. This time the form is no longer empty (unbound)

    so the HTML form will be populated with the data previously submitted, where it can be edited and corrected as required.

    当我们调用is_valid()方法时,如果不是True,我们将带着form 返回template, 但这次不同,这个表单将不再是空的,因为HTMLform 将先前提交的数据收集起来填充到form中,这样我们按照需求再次编辑并且更正它。

    If is_valid() is True, we’ll now be able to find all the validated form data in its cleaned_data attribute. We can use this data to

    update the database or do other processing before sending an HTTP redirect to the browser telling it where to go next.

    如果是True,我们可以通过cleaned_data 属性来获得这些有效的表单数据,我们能利用这些数据去更新数据库,或者其他处理,在发送redirct给浏览器之前

    另外还可以自定义一些有效性的规则

    from django import forms
    from django.core.exceptions import ValidationError
    from blog.models import Userinfo
    class Registerform(forms.Form):
        def __init__(self,requestpost,request=None):
            self.request = request
            super().__init__(requestpost)
        username=forms.CharField(min_length=5,max_length=12,
                                 widget=forms.TextInput(attrs={'placeholder':'用户名',
                                                               'class':'form-control input-sm'}))
        password=forms.CharField(min_length=8,max_length=15,widget=forms.PasswordInput(attrs={'placeholder':'密码',
                                                               'class':'form-control input-sm'}))
        re_password=forms.CharField(min_length=8,max_length=15,widget=forms.PasswordInput(attrs={'placeholder':'再次输入密码',
                                                               'class':'form-control input-sm'}))
        email=forms.EmailField(widget=forms.EmailInput(attrs={'placeholder':'邮箱',
                                                               'class':'form-control input-sm'}))
        verify_code=forms.CharField(widget=forms.TextInput(attrs={
                                                          'class':'form-control input-sm'}))
    
        def clean_username(self):
    
            # if self.cleaned_data['username'].isdigit() or self.cleaned_data['username'].isalpha():
            #     raise ValidationError('用户名必须是字母和数字组合')
            if Userinfo.objects.filter(username=self.cleaned_data['username']).exists():
                raise ValidationError('用户已存在')
            else:
                return self.cleaned_data['username']
        def clean_verify_code(self):
            if self.cleaned_data['verify_code'].upper() == self.request.session.get('verifycode').upper():
                return self.cleaned_data['verify_code']
            else:
                raise ValidationError('验证码输入不正确')
            pass
        def clean(self):
            if self.cleaned_data.get('password',None) and self.cleaned_data.get('re_password',None):
                if self.cleaned_data['password'] == self.cleaned_data['re_password']:
                    return self.cleaned_data
                else:
                    raise ValidationError('两次密码必须一致')
            return self.cleaned_data
    View Code

    file uploads

    当处理文件上传的时候,文件数据将会保存在request.FILES

    from django import forms
    
    class UploadFileForm(forms.Form):
        title = forms.CharField(max_length=50)
        file = forms.FileField()

    表单穿的数据都会保存在request.FILES  它是一个字典,包含每个filefield字段的key  可以通过request.FILES['file']拿到上传文件的数据

    只有请求方式是POST,并且 表单post request 有这个属性  enctype="multipart/form-data",request.FILES才不会是empty



     

  • 相关阅读:
    为什么有时候程序出问题会打印出“烫烫烫烫...
    VC++共享数据段实现进程之间共享数据
    IEEE浮点数float、double的存储结构
    前端智勇大闯关
    Python:高级主题之(属性取值和赋值过程、属性描述符、装饰器)
    来认识下less css
    Koala Framework
    在使用Kettle的集群排序中 Carte的设定——(基于Windows)
    标准库类型
    iOS多线程的初步研究1
  • 原文地址:https://www.cnblogs.com/yuyang26/p/7455001.html
Copyright © 2020-2023  润新知