轻松使用DjangoForm组件与ModelForm

一.Django Form组件

# 定义Form组件
from django import forms

class RegForm(forms.Form):
    username = forms.CharField(lable='用户名', min_length=6)
    password = forms.ChatField(lable='密码')

# 使用Form组件需要实例化From类    
    
def register(request):
    # 实例化RegForm类
    form_obj = RegForm()
    
    return render(request, 'register.html', context={'form': form_obj})
# 在模板中使用
<form action="" method="post" novalidate>  # novalidate 不在前端做校验
	{% csrf_token %}
    # 一次性生成所有的input框
    {{ form_obj.as_p }}
	<button>注册</button>
</form>


{{ form_obj.user }} 该字段的input框
{{ form_obj.user.label }} 该字段的提示信息
{{ form_obj.user.id_for_label }}   该字段的input框的id

{{ form_obj.errors }} 所有字段的错误
{{ form_obj.username.errors.0 }} 该字段的错误

使用form组件校验数据

def register(request):
    from_obj = RegForm()
    if request.method == 'POST':
        form_obj = RegForm(request.POST) # 包含了用户提交的数据
        if form.obj.is_valid():  # 对数据进行校验

            #is_valid返回一个错误字典
            #只要这个字典中有值,就意味着发生了错误,那么校验失败,如果字典中没有值,那么校验成功
            
            # 校验成功
            return HttpResponse('注册成功')
     return render(request, 'register.html', context={'form_obj': form_obj})

Form组件常用字段

# 文本类型
forms.CharField()
# 单选择类型 默认就是select
forms.ChoiceFiedld(choices=(('1', '男'), ('2', '女')))
# 多选类型	默认就是select
forms.MultipleChoiceField()
# 邮箱类型
forms.EmailField()

常用的字段参数

initial='xx'  # 设置默认值

# 自定义错误提示
error_messages = {
    'required': '不不能为空',
    'min_length': '用户名最少6位'
}

widget = forms.PasswordInput # 插件 修改input的type
widget = forms.CheckboxInput # 单选Checkbox

required = True # 是否必填
disabled = True # 是否禁用

choices # 用户选择的数据(元组的格式)

validators = [校验函数]  # 校验参数

校验器

# 1.定义函数
def check_name(value):
    if 'cjh' in value:
        raise ValidationError('不符合规则')
# 将校验函数加入到Form组件中
class RegFrom(forms.Form):
    username = forms.CharField(validators=[check_name])
    
    
# 2.使用内置函数 校验手机号验证
class RegFrom(forms.Form):
    username = forms.CharField(validators=[check_name])
    phone = forms.CharFiedld(validtors=[RegexValidator(r'^1[3-9]\d{9}$', '手机格式不正确')])

钩子函数

1.局部钩子

class RegForm(forms.Form):
    username = forms.CharField()

    # 定义局部钩子函数clean_字段(只针对于一个字段username做校验)
    def clean_username(self):
        value = self.cleaned_data.get('username') # 获取清理后的数据
        if 'cjh' in value:
            raise ValidationError('不符合规范')
        return value

2.全局钩子

class RegForm(forms.Form):
    username = forms.CharField()
    pwd = forms.CharField()
    re_pwd = forms.CharField()

    # 定义全局钩子函数 clean
    def clean(self):
        pwd = self.cleaned_data.get('pwd') # 获取清理后的数据re_
        re_pwd = self.cleaned_data.get('re_pwd')
        if pwd != re_pwd:
            # 将错误信息加入到某个字段中
            self.add_error('re_pwd', '两次密码不一致')
            raise ValidationError('两次密码不一致')
        return self.cleaned_data

is_valid()的流程

1.执行一个full_clean方法

​	1.1定义一个错误字典和cleaned_data = {}  # 存放已经校验过的数据

​	1.2执行self._clean_fields()

​	     循环所有的字段

​		 对一个字段进行内置的校验、校验器的校验、局部钩子的校验

​		 校验不通过,错误字典中有该字段的错误信息

​		 所有校验通过,self.cleaned_data有该字段的值

    1.3执行全局钩子

二.ModelForm

# ModelForm按照models的字段添加form的字段
class RegForm(forms.ModelForm):
    # Meta是对默认的字段进行设置,而在RegForm下面可以重写或者新增字段
    password = forms.CharField(widget=forms.PasswordInput, label='密码', min_length=6,
                               error_messages={'required': '密码必须填写'})
    re_password = forms.CharField(widget=forms.PasswordInput, label='确认密码', min_length=6)
    
    class Meta:
        # 根据模型User形成form
        model = models.User
        
        # 从User模型中选择要形成的form字段
        # fields = '__all__'  # 所有的
        fields = ['username', 'password', 'position', 'company', 'phone']  # 某些字段
        
        # exclude = ['']   # 排除哪些字段
        # labels = {'username': '用户名'}
        widgets = {
            # 插件
            'password': forms.PasswordInput   # 密码字段设置为密文
        }

        error_messages = {
            # 设置错误信息
            'username': {
                'required': '用户名必须填写'
            }
        }
        
	# 校验手机号码的局部钩子函数
    def clean_phone(self):
        phone = self.cleaned_data.get('phone')
        if re.match(r'^1[3-9]\d{9}$', phone):
            return phone
        raise ValidationError('手机号格式不正确')

    # 校验两次密码的全局钩子
    def clean(self):
        self._validate_unique = True  # 校验数据库唯一
        password = self.cleaned_data.get('password')
        re_password = self.cleaned_data.get('re_password')
        if password == re_password:
            return self.cleaned_data
        self.add_error('re_password', '两次密码不一致')
        raise ValidationError('两次密码不一致')

# 与RegForm对应的视图函数
def register(request):
    # 实例化RegForm类,构成表单
    regform_obj = RegForm()
    # 判断请求方法是否为POST
    if request.method == 'POST':
        # 获取RegForm中用户提交的数据
        regform_obj = RegForm(request.POST)
        # 判断获取的regform_obj对象内容是否有错
        if regform_obj.is_valid():
            # 注册成功
            # 将数据插入到用户表中
            # regform_obj.cleaned_data.pop('re_password')
            # models.User.objects.create(**regform_obj.cleaned_data)  # **字典 将字典打散,变为一个一个的键值对
            # ModelForm可直接使用save将数据保存到数据库
            regform_obj.save()
            return redirect('login')

    return render(request, 'register.html', {'regform_obj': regform_obj})
# register.html  模板中
{{ regform_obj.字段 }}   # input框
{{ regform_obj.字段.label }}  # label提示
{{ regform_obj.字段.id_for_label }}  # input框的id
{{ regform_obj.字段.errors.0 }}  # 字段错误提示
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天意不可违.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值