ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Django之forms组件

2021-06-26 10:00:42  阅读:136  来源: 互联网

标签:name form self 校验 Django forms 组件 data


目录

Django之forms组件

一 forms组件介绍

1) 注册功能,登录功能,前端需要校验(字段长度,邮箱是否合法。。。)
2) 前端校验可以没有,后端校验是必须的,使用传统方式  if判断写的很多
3) 借助于 forms组件,可以快速实现字段的校验
	from django.forms import Form

二 校验字段功能

### 1 写一个类,类里写要校验的字段
class MyForm(forms.Form):
    # 校验这个字段,最大长度是32,最小长度是3
    name = forms.CharField(required=False, max_length=32, min_length=3,label='用户名')
    email = forms.EmailField(label='邮箱')
    age=forms.IntegerField(max_value=200,min_value=0,label='年龄')
    
    
### 2 视图函数中使用
def register(request):
    # 数据可以是从前端传过来的,也可以是自己后台的数据
    # 现在有以下数据
    data={'name':'lxx','email':'33333@qq.com','age':900}
    # data={'email':'33333@qq.com','age':100}
    # data={'age':100}
    # 校验数据是否合法
    # 实例化得到form对象,把要校验的数据传入
    form=myforms.MyForm(data)
    # 校验数据:form.is_valid() 返回布尔类型

    if form.is_valid():
        print('校验通过')
        # 校验通过的数据
        print(form.cleaned_data)  # 不一定是上面传入的数据
    else:
        print(form.cleaned_data)
        print('校验失败')
        # 哪个字段失败了?失败的原因是什么
        print(form.errors)
        print(type(form.errors))
        from django.forms.utils import ErrorDict
        #### 重写了__str__
        print(form.errors.as_json())
        print(form.errors.as_data())

        # form.errors.as_ul()  # 是为了渲染模板

    return HttpResponse('ok')
'''
注意点:
    1 调用is_valid()后,有form.errors和form.cleaned_data
    2 form.cleaned_data不管成功与失败,都会有值,不一定是传入的值
    3 form.errors看了源码,as_data,as_ul...
'''

三 渲染标签功能

## 视图函数
def register(request):
    if request.method=='GET':
        form=myforms.MyForm()
        return render(request,'register.html',{'form':form})
    elif request.method=='POST':
        # 数据校验
        form=myforms.MyForm(request.POST)
        if form.is_valid():
            print('校验通过,存数据库')
        else:
            print(form.errors.as_data())
            print('校验失败,返回错误')
        return HttpResponse('ok')
    
    
 ## 模板
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<hr>
<h1>手动创建模板</h1>
<form action="" method="post">
    <p>用户名:<input type="text" name="name"></p>
    <p>邮箱:<input type="text" name="email"></p>
    <p>年龄:<input type="text" name="age"></p>
    <p><input type="submit" value="提交"></p>
</form>

<hr>
<h1>半自动渲染模板1</h1>
<form action="" method="post">
    <p>用户名:{{ form.name }}</p>
    <p>邮箱:{{ form.email }}</p>
    <p>年龄:{{ form.age }}</p>
    <p><input type="submit" value="提交"></p>
</form>

<h1>半自动渲染模板2(用的最多)</h1>
<form action="" method="post">
    <p>{{ form.name.label }}--{{ form.name }}</p>
    <p>{{ form.email.label }}---{{ form.email }}</p>
    <p>{{ form.age.label }}---{{ form.age }}</p>
    <p><input type="submit" value="提交"></p>
</form>

<h1>半自动渲染模板3(用的最多)</h1>
<form action="" method="post">
    {% for foo in form %}
       <p>{{ foo.label }} :{{ foo }}</p>
    {% endfor %}

    <p><input type="submit" value="提交"></p>
</form>

<h1>全自动(了解)</h1>
<form action="" method="post">
{#    {{ form.as_ul }}#}
    {{ form.as_p }}
{#    <table>#}
{#        {{ form.as_table }}#}
{#    </table>#}

    <p><input type="submit" value="提交"></p>
</form>
</body>
</html>

四 渲染错误信息功能

1) form对象.errors 字典
	-form对象的错误信息是一个字典
2) name对象.errors
	-form对象下的name对象,有具体的错误信息

## 视图函数
def register(request):
    if request.method=='GET':
        form=myforms.MyForm()
        return render(request, 'register.html',{'form':form})
    else:
        form=myforms.MyForm(request.POST)
        if form.is_valid():
            return redirect('http://www.baidu.com')
        else:
            return render(request, 'register.html',{'form':form})

## 模板
 <form action="" method="post" novalidate>
	{% for foo in form %}
	<div class="form-group">
        <label for="">{{ foo.label }}</label>
            {{ foo }}
            <span class="text-danger pull-right">{{ foo.errors }}</span>
        </div>
	{% endfor %}
	<div class="text-center">
		<input type="submit" value="提交" class="btn btn-danger">
	</div>
</form>

五 组件的参数匹配值

# 定制模板中的显示样式,及配置类
# widget=widgets.PasswordInput(attrs={'class': 'form-control'})
# 错误信息中文显示
	error_messages={'min_length': '太短了小伙子'}


class MyForm(forms.Form):
    # 校验这个字段,最大长度是32,最小长度是3
    name = forms.CharField(required=False, max_length=32, min_length=3, label='用户名',
                           widget=widgets.TextInput(attrs={'class': 'form-control'}),
                           error_messages={'min_length': '太短了小伙子'})
    password = forms.CharField(required=False, max_length=32, min_length=3, label='密码',
                               widget=widgets.PasswordInput(attrs={'class': 'form-control'}),
                               error_messages={'min_length': '太短了小伙子'})
    re_password = forms.CharField(required=False, max_length=32, min_length=3, label='确认密码',
                                  widget=widgets.PasswordInput(attrs={'class': 'form-control'}),
                                  error_messages={'min_length': '太短了小伙子'})
    email = forms.EmailField(label='邮箱', error_messages={'required': '小惠子,这个必填'},
                             widget=widgets.TextInput(attrs={'class': 'form-control'}))
    age = forms.IntegerField(max_value=200, min_value=0, label='年龄',
                             widget=widgets.TextInput(attrs={'class': 'form-control'}))
    text = forms.CharField(label='个人简介', widget=widgets.Textarea(attrs={'class': 'form-control'}))
    date = forms.CharField(label='出生日期', widget=widgets.DateInput(attrs={'class': 'form-control'})

六 局部钩子和全局钩子

## 局部钩子的使用
    # 1 在自定义的Form类中写 clean_字段名
    # 2 取出字段的真正值,name=self.cleaned_data.get('name')
    # 3 判断自己的规则,如果判断失败,抛出ValidationError
    # 4 如果通过,return name

# 局部钩子
    def clean_name(self):
        # name对应的值,如何取到?
        name = self.cleaned_data.get('name')
        if name.startswith('sb'):
            # 不让校验通过
            raise ValidationError('不能以sb开头')
        else:
            # 校验通过,返回name
            return name


# 全局钩子
    def clean(self):
        # name=self.cleaned_data.get('name')
        # print(name)
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')
        if password == re_password:
            return self.cleaned_data
            # return {'lqz':"nb"}
        else:
            raise ValidationError('两次密码不一致')

七 form组件校验源码

1) # 读的入口是:
    form.is_valid()--->self.errors(BaseForm类)---》self.full_clean()(BaseForm类)--》
    -self._clean_fields(局部数据校验)和self._clean_form(全局数据校验)

2) self._clean_fields(BaseForm类)
		for name, field in self.fields.items():
            try:
                # 字段自己的校验(最大值,最小值,是不是邮箱格式)
                value = field.clean(value)
                self.cleaned_data[name] = value
                if hasattr(self, 'clean_%s' % name): # 反射判断有没有clean_字段名
                    value = getattr(self, 'clean_%s' % name)()
                    self.cleaned_data[name] = value
            except ValidationError as e:
                self.add_error(name, e)
                
3) self._clean_form(BaseForm类)  # 全局钩子
	 	try:
           cleaned_data = self.clean()  # self.clean执行的是自己类的clean方法
        except ValidationError as e:
           self.add_error(None, e)
        
# 面向切面编程(AOP  OOP:面向对象编程)

标签:name,form,self,校验,Django,forms,组件,data
来源: https://www.cnblogs.com/chaochaofan/p/14932314.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有