10、Django框架-- 分页器终极用法、forms组件(检验字段、渲染标签、渲染错误信息、参数配置、全局钩子、局部钩子)

1 分页器终极用法

1.1 后端

def books_page(request):
    current_num = int(request.GET.get('page_num', 1))
    book_list = models.Books.objects.all()

    paginator = Paginator(book_list, 20)
    try:
        page = paginator.page(current_num)
    except Exception as e:
        current_num = 1
        page = paginator.page(current_num)

    if paginator.num_pages > 11:
        if current_num - 5 < 1:
            page_range = range(1, 12)
        elif current_num + 5 > paginator.num_pages:
            page_range = range(paginator.num_pages - 10, paginator.num_pages + 1)
        else:
            page_range = range(current_num - 5, current_num + 6)
    else:
        page_range = paginator.page_range

    return render(request, 'book_page.html', locals())

1.2 前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
    <script src="/static/bootstrap-3.3.7-dist/js/bootstrap.min.js"></script>
    <script src="/static/jquery-3.3.1.js"></script>

</head>
<body>
<div class="container-fluid">
    <div class="row">

        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-success">
                <div class="panel-heading">
                    <h3 class="panel-title">图书列表展示</h3>
                </div>
                <div class="panel-body">
                    <table class="table table-striped">
                        <thead>
                        <tr>
                            <th>id</th>
                            <th>书名</th>
                            <th>价格</th>
                            <th>出版社</th>
                        </tr>
                        </thead>
                        <tbody>
                        {% for book in page.object_list %}
                            <tr>
                                <td>{{ book.id }}</td>
                                <td>{{ book.name }}</td>
                                <td>{{ book.price }}</td>
                                <td>{{ book.publish }}</td>
                            </tr>
                        {% endfor %}
                        </tbody>
                    </table>
                    <div class="text-center">
                        <nav aria-label="Page navigation">
                            <ul class="pagination">
                                {% if page.has_previous %}
                                    <li>
                                        <a href="/books_page/?page_num={{ page.previous_page_number }}"
                                           aria-label="Previous">
                                            <span aria-hidden="true">&laquo;</span>
                                        </a>
                                    </li>
                                {% else %}
                                    <li class="disabled">
                                        <a href="" aria-label="Previous">
                                            <span aria-hidden="true">&laquo;</span>
                                        </a>
                                    </li>
                                {% endif %}

                                {% for foo in page_range %}
                                    {% if current_num == foo %}
                                        <li class="active"><a href="/books_page/?page_num={{ foo }}">{{ foo }}</a></li>
                                    {% else %}
                                        <li><a href="/books_page/?page_num={{ foo }}">{{ foo }}</a></li>
                                    {% endif %}
                                {% endfor %}

                                {% if page.has_next %}
                                    <li>
                                        <a href="/books_page/?page_num={{ page.next_page_number }}" aria-label="Next">
                                            <span aria-hidden="true">&raquo;</span>
                                        </a>
                                    </li>
                                {% else %}
                                    <li class="disabled">
                                        <a href="" aria-label="Next">
                                            <span aria-hidden="true">&raquo;</span>
                                        </a>
                                    </li>
                                {% endif %}
                            </ul>
                        </nav>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<div>
</div>
</body>
</html>

2 forms组件之校验字段

# 第一步:定义一个类,继承forms.Form
# 第二步:在类中写字段,要校验的字段,字段属性就是校验规则
# 第三步:实例化得到一个Form对象,把要校验的数据传入
# 第四步:调用register_form.is_valid()校验,校验通过就是True
# 第五步:校验通过有register_form.cleaned_data
# 第六步:校验不通过 register_form.errors
#定义类
from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError
class RegisterForm(forms.Form):
    name = forms.CharField(max_length=8, min_length=3, label='用户名')
    password = forms.CharField(max_length=8, min_length=3, label='密码')
    re_password = forms.CharField(max_length=8, min_length=3, label='确认密码')
    email = forms.EmailField(label='邮箱')
   

#在视图中使用
register_form = RegisterForm(request.POST)
if register_form.is_valid():
      # 校验通过,存
      # 取出校验通过的数据
      print('校验通过')
      print(register_form.cleaned_data)
else:
     # 校验不通过
     print('校验不通过')
     print(register_form.errors)

3 forms组件之渲染标签

3.1 渲染方式一

<h2>通过form自动渲染一</h2>
<form action="" method="post">
    <p>用户名 {{ form.name }}</p>
    <p>密码 {{ form.password }}</p>
    <p>确认密码 {{ form.re_password }}</p>
    <p>邮箱 {{ form.email }}</p>
    <input type="submit" value="提交">

</form>

3.2 渲染方式二

<h2>通过form自动渲染二(基本用这种)</h2>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form action="" method="post" novalidate>
                {% for item in form %}
                    <div class="form-group">
                        <p>{{ item.label }}{{ item }} <span style="color: red">{{ item.errors.0 }}</span></p>
                    </div>

                {% endfor %}
                <input type="submit" value="提交"><span style="color: red">{{ error }}</span>

            </form>
        </div>
    </div>
</div>

3.3 渲染方式三

<h2>通过form自动渲染三</h2>
<form action="" method="post">
    {{ form.as_p }}
    {#    {{ form.as_table }}#}
    {#    {{ form.as_ul }}#}

</form>

4 forms组件之渲染错误信息

4.1 前端

<h2>通过form自动渲染二(基本用这种)</h2>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form action="" method="post" novalidate>
                {% for item in form %}
                    <div class="form-group">
                        <p>{{ item.label }}{{ item }} <span style="color: red">{{ item.errors.0 }}</span></p>
                    </div>

                {% endfor %}
                <input type="submit" value="提交"><span style="color: red">{{ error }}</span>

            </form>
        </div>
    </div>
</div>

4.3 后端

from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError

class RegisterForm(forms.Form):
    name = forms.CharField(max_length=8, min_length=3, label='用户名',
                           error_messages={'max_length': '最长为8', 'min_length': '最短为3'},
                           widget=widgets.TextInput(attrs={'class':'form-control'}))
    password = forms.CharField(max_length=8, min_length=3, label='密码',
                               error_messages={'required': '该字段必填'},
                               widget=widgets.PasswordInput(attrs={'class':'form-control'}))
    re_password = forms.CharField(max_length=8, min_length=3, label='确认密码',
                                  widget=widgets.PasswordInput(attrs={'class':'form-control'}))
    email = forms.EmailField(label='邮箱',
                             error_messages={'required': '必填', 'invalid': '必须是邮箱格式'},
                             widget=widgets.TextInput(attrs={'class':'form-control'}))
    

5 forms组件参数配置

name = forms.CharField(max_length=8, min_length=3, label='用户名',error_messages={'max_length': '最长为8', 'min_length': '最短为3'},widget=widgets.TextInput(attrs={'class':'form-control'}))

6 forms组件全局钩子,局部钩子(总代码)

6.1 后端

from django import forms
from django.forms import widgets
from django.core.exceptions import ValidationError

class RegisterForm(forms.Form):
    name = forms.CharField(max_length=8, min_length=3, label='用户名',
                           error_messages={'max_length': '最长为8', 'min_length': '最短为3'},
                           widget=widgets.TextInput(attrs={'class':'form-control'}))
    password = forms.CharField(max_length=8, min_length=3, label='密码',
                               error_messages={'required': '该字段必填'},
                               widget=widgets.PasswordInput(attrs={'class':'form-control'}))
    re_password = forms.CharField(max_length=8, min_length=3, label='确认密码',
                                  widget=widgets.PasswordInput(attrs={'class':'form-control'}))
    email = forms.EmailField(label='邮箱',
                             error_messages={'required': '必填', 'invalid': '必须是邮箱格式'},
                             widget=widgets.TextInput(attrs={'class':'form-control'}))
    def clean_name(self):#name字段的局部钩子
        # 校验名字不能以sb开头
        name=self.cleaned_data.get('name')
        if name.startswith('sb'):
            # 校验不通过,必须抛异常,
            raise ValidationError('不能以sb开头')
        else:#校验通过,返回name对应的值

            return name

    def clean(self): # 全局钩子
        password=self.cleaned_data.get('password')
        re_password=self.cleaned_data.get('re_password')
        if re_password==password:
            #校验通过
            return self.cleaned_data
        else:
            raise ValidationError('两次密码不一致')




from app01 import models


def register(request):
    if request.method == 'GET':
        # 生成一个空form对象
        register_form = RegisterForm()
        return render(request, 'register.html', {'form': register_form})

    else:
        # 实例化得到对象,传入要校验的数据
        # register_form=RegisterForm(data=request.POST)
        register_form = RegisterForm(request.POST)
        if register_form.is_valid():
            # 校验通过,存
            # 取出校验通过的数据
            print('校验通过')
            print(register_form.cleaned_data)
            register_form.cleaned_data.pop('re_password')
            models.User.objects.create(**register_form.cleaned_data)
            return HttpResponse('ok')

        else:
            # 校验不通过
            print('校验不通过')
            print(register_form.errors)
            error=register_form.errors.get('__all__')[0]
            print(type(register_form.errors.as_json))
            from django.forms.utils import ErrorDict
            # name_error=register_form.errors.get('name')[0]
            return render(request, 'register.html', {'form': register_form,'error':error})

6.2 前端

<h2>通过form自动渲染二(基本用这种)</h2>
<div class="container-fluid">
    <div class="row">
        <div class="col-md-6 col-md-offset-3">
            <form action="" method="post" novalidate>
                {% for item in form %}
                    <div class="form-group">
                        <p>{{ item.label }}{{ item }} <span style="color: red">{{ item.errors.0 }}</span></p>
                    </div>

                {% endfor %}
                <input type="submit" value="提交"><span style="color: red">{{ error }}</span>

            </form>
        </div>
    </div>
</div>
posted @ 2022-03-10 13:14  简爱cx  阅读(75)  评论(0编辑  收藏  举报