Django之form组件

Django的form组件就是把model和form组合气起来

缓存机制

  就比如我们去访问一个网站,然后发起一个请求,那么此时服务器就会去帮我们去数据库进行增删查改渲染页面。

然后返回一个我们想要的页面

但是当这个网站的访问量很大,每一次进行的后台操作,都会消耗服务器的资源,那么此时,就会用缓存来减轻压力。将经常用到的数据给缓存起来,当有用户需要的时候就直接给,这样就会减少资源浪费。

Django提供的6种缓存机制

开发调试缓存

内存缓存

文件缓存

数据库缓存

Memcache缓存(使用python-memcache模块)

Memcacae缓存(使用pylibmc模块)

经常用到的是文件缓存和Memcahe缓存

 

models常用的13个API查询

1.all          查询全部

2.filter      过滤(后面加条件)

3.get         只能查询确切的一条,查询不到或者查询到多条都会报错

4.exclude  除了.....和filter是相反的

 5.order_by 排序,默认升序排序,必须由参数,倒叙就在参数前面加负号即可  

   举例:Book.objects.all().order_by("-price")

6.values

7.values_list

8.distinct   去重

9.count      计数

10.first

11.last

12.Book.objects.all()[2:5]  

13.exist

有关only和defer

d = models.User.objects.all().only("name","email")  #拿到的还是一个QuerySet集合,仅仅取name和email
for item in d:
    print(item.id)
    print(item.name)
    print(item.pwd)   #只要表里有这个字段,一样会取到值,额外的会再发一次请求

d = models.User.objects.all().defer("name","email") #阻止,不取name和email
for item in datalist:
    print(item.id)
    print(item.pwd

 ps:如果用only的话就尽量用only里面的字段,用别的查询效率太低,我们尽量的去减少连接数据库的次数

Form组件

form组件的作用

  1.用户请求验证

   2.自动生成错误信息

   3.根据我们的情况而定,就比如注册时我们写错了用户名,但是别的信息正确,就只会让我们再次输入用             户名,其余的数据保留

    4.在form表单中会简单很多,由三种方法,具体在下面介绍

          5.如果全部输入正确就是打包提交

widgets

每一个表单都有一个对应的widgets类,它对应一个HTML表单widget,

   # 给html添加属性

widget=widgets.TextInput(attrs={"class": "form-control"}),

Form组件的字段

一般我们会在自己创建的应用下面创建一个py文件

forms.py

form django import forms


class RegisterForm(forms.Form):
    user = forms.CharField(max_length=18, min_length=4,
                           widget=widgets.TextInput(attrs={"class": "form-control"}),
                           error_messages={
                               "required": "用户名不能为空",
                               "max_length": "最大长度为18",
                               "min_length": "最小长度为4"
                           }
                           )
    pwd = forms.CharField(max_length=20, min_length=4,
                          widget=widgets.PasswordInput(attrs={"class": "form-control"}),
                          error_messages={
                              "required": "密码不能为空",
                              "max_length": "最大长度为20",
                              "min_length": "最小长度为4"

                          })
    repeat_pwd = forms.CharField(max_length=20, min_length=4,
                                 widget=widgets.PasswordInput(attrs={"class": "form-control"}),
                                 error_messages={
                                     "required": "密码不能为空",
                                     "max_length": "最大长度为20",
                                     "min_length": "最小长度为4"

                                 })
    email = forms.EmailField(max_length=20,
                             # 给html添加属性
                             widget=widgets.TextInput(attrs={"class": "form-control"}),
                             error_messages={
                                 "required": "邮箱不能为空",
                                 "max_length": "最大长度为20",
                                 "invalid": "格式错误"
                             }
                             )
    tel = forms.CharField(

            widget=widgets.TextInput(attrs={"class": "form-control"}),
            error_messages={
                "required": "电话号码不能为空",
            }
    )

  

字段的数据

 不管表单提交的是什么数据,一旦通过调用is_valid()成功验证返回True,那么验证后的表单数据将位于form.cleaned_data的字典中,

这些数据已经转换为python类型

但是此时依然可以在从request.POST中直接访问到未验证到的数据,但是访问验证后的数据更好一些(具体的在例子中具解释)

绑定和未绑定表单的区别

未绑定的表单没有关联的数据。当渲染给用户时,它将为空或包含默认的值。
绑定的表单具有提交的数据,因此可以用来检验数据是否合法。如果渲染一个不合法的绑定的表单,
它将包含内联的错误信息,告诉用户如何纠正数据。
 

表单在html中渲染的三种方法

1.用p标签包起来的

<form action="" novalidate method="post">
{% csrf_token %}
{{ form_obj.as_p }}
<input type="submit">
 </form>

2.尽量用这一种

 <form action="" novalidate method="post">
{% csrf_token %}
<div>
<label for="">用户名</label>
{{ form_obj.user }} <span>{{ form_obj.errors.user.0 }}</span>
</div>
<div>
<label for="">密码</label>
{{ form_obj.pwd }}<span>{{ form_obj.errors.pwd.0 }}</span>
</div>
<input type="submit">
</form>

3.循环 

form action="" novalidate method="post">
{% csrf_token %}
{% for field in form_obj %}
<div>
<label for="">{{ field.label }}</label>
 {{ field }}
 </div>
{% endfor %}
<input type="submit">
</form>  

Form组件的钩子 

局部钩子

这个的意思也就是我们在字段里面没有设置,但是却是我们需要的,就单拿出来进行校验

因为是局部的,也就是针对一个字段的,所以名字用clean_user(字段名)

 # 校验用户名(局部钩子)
    def clean_user(self):
        val = self.cleaned_data.get("user")
        user_obj = models.User.objects.filter(user=val)

        if not val.isdigit() and not user_obj:
            return val
        elif user_obj:
            raise ValidationError("该用户已注册")
        else:
            raise ValidationError("用户名不能为纯数字")  

全局钩子

针对多个联合校验,所以直接用clean

 

# 全局钩子函数
    def clean(self):
        pwd = self.cleaned_data.get("pwd")
        repeat_pwd = self.cleaned_data.get("repeat_pwd")
        if pwd == repeat_pwd:
            return self.cleaned_data
        else:
            raise ValidationError("两次密码不一致")

 

 

注册举例

(这里因为东西少,所以forms.py和views在一起写着)

urls


from django.conf.urls import url
from django.contrib import admin
from app01 import views

urlpatterns = [
    # url(r'^admin/', admin.site.urls),
    url(r'^register/',views.register),

]

views中

from django.shortcuts import render, redirect, HttpResponse
from app01 import models
from django import forms
from django.forms import widgets
from django.forms import ValidationError


# Create your views here.
class RegisterForm(forms.Form):
    user = forms.CharField(max_length=18, min_length=4,
                           widget=widgets.TextInput(attrs={"class": "form-control"}),
                           error_messages={
                               "required": "用户名不能为空",
                               "max_length": "最大长度为18",
                               "min_length": "最小长度为4"
                           }
                           )
    pwd = forms.CharField(max_length=20, min_length=4,
                          widget=widgets.PasswordInput(attrs={"class": "form-control"}),
                          error_messages={
                              "required": "密码不能为空",
                              "max_length": "最大长度为20",
                              "min_length": "最小长度为4"

                          })
    repeat_pwd = forms.CharField(max_length=20, min_length=4,
                                 widget=widgets.PasswordInput(attrs={"class": "form-control"}),
                                 error_messages={
                                     "required": "密码不能为空",
                                     "max_length": "最大长度为20",
                                     "min_length": "最小长度为4"

                                 })
    email = forms.EmailField(max_length=20,
                             # 给html添加属性
                             widget=widgets.TextInput(attrs={"class": "form-control"}),
                             error_messages={
                                 "required": "邮箱不能为空",
                                 "max_length": "最大长度为20",
                                 "invalid": "格式错误"
                             }
                             )
    tel = forms.CharField(

            widget=widgets.TextInput(attrs={"class": "form-control"}),
            error_messages={
                "required": "电话号码不能为空",
            }
    )

    # 校验用户名(局部钩子)
    def clean_user(self):
        val = self.cleaned_data.get("user")
        user_obj = models.User.objects.filter(user=val)

        if not val.isdigit() and not user_obj:
            return val
        elif user_obj:
            raise ValidationError("该用户已注册")
        else:
            raise ValidationError("用户名不能为纯数字")




    # 全局钩子函数
    def clean(self):
        pwd = self.cleaned_data.get("pwd")
        repeat_pwd = self.cleaned_data.get("repeat_pwd")
        if pwd == repeat_pwd:
            return self.cleaned_data
        else:
            raise ValidationError("两次密码不一致")

    def clean_tel(self):
        te = self.cleaned_data.get("tel")
        if te.isdigit():
            return te
        else:
            raise ValidationError("电话号码必须是数字")


def register(request):
    if request.method == "POST":
        print("POST:", request.POST)
        form_obj = RegisterForm(request.POST)
        if form_obj.is_valid():
            # 这里的意思是数据全部合格
            # 取出合格数据
            print(form_obj.cleaned_data)
            return HttpResponse("登录成功")
        else:
            print(form_obj.errors)
            repeat_pwd = form_obj.errors.get("__all__")  # 两次密码不一致就来这里打印错误信息
            print(form_obj.cleaned_data)
            return render(request, "register.html", {"form_obj": form_obj,})

    form_obj = RegisterForm()  # 这个是没有数据的表单
    return render(request, "register.html", {"form_obj": form_obj})

  

templates

regirster.py


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script src="/static/bootstrap/dist/css/bootstrap.min.css"></script>
<div class="container" >
    <div class="row">
<form class="form-horizontal " action="" method="post" novalidate>
    {#    novalidate 不让浏览器做验证#}
    {% csrf_token %}
    <div class="form-group">
        <label  class="control-label" for="">用户名:</label>
        <div class="input-group">
            {{ form_obj.user }}<span>{{ form_obj.errors.user.0 }}</span>
        </div>

    </div>
    <div class="form-group">
        <label  class="control-label" for="">密码:</label>
        <div class="input-group">
            {{ form_obj.pwd }}<span>{{ form_obj.errors.pwd.0 }}</span>
        </div>

    </div>
    <div class="form-group">
        <label  class="control-label" for="">确认密码:</label>
        <div class="input-group">
            {{ form_obj.repeat_pwd }}<span>{{ form_obj.errors.repeat_pwd.0 }}</span>
        </div>

    </div>
    <div class="form-group">
        <label  class="control-label" for="">邮箱:</label>
        <div class="input-group">
            {{ form_obj.email }} <span>{{ form_obj.errors.email.0 }}</span>
        </div>

    </div>
    <div class="form-group">
        <label class="control-label" for="">手机号:</label>
        <div class="input-group">
            {{ form_obj.tel }} <span>{{ form_obj.errors.tel.0 }}</span>
        </div>

    </div>
    <div class="form-group">
    <input type="submit" value="提交">
        </div>
</form>
        </div>
    </div>
</body>
</html>


 

  

 

 
posted @ 2018-01-31 14:06  兰博~~  阅读(200)  评论(0编辑  收藏  举报