• Django组件之forms组件


    核心功能:校验字段和钩子

    注意:我会省略部分相同代码

    校验的简单例子:

    views.py

      1: from from django import forms
    
      2: class UserForm(forms.Form):
    
      3: 
    
      4:     name = forms.CharField(min_length=4)
    
      5:     email = forms.EmailField()
    
      6: 
    
      7: def func(request):
    
      8: 	if request.method == "POST":
    
      9: 
    
     10: 		# 对于不包含的类中的字段,forms并不关心
    
     11: 		form = UserForm({"name":"yuan", "email":"123@qq.com","xxx":"xxx"})
    
     12: 		# form = UserForm({"name":"yu", "email":"123@qq.com","xxx":"xxx"})
    
     13: 
    
     14: 		# 检测是否通过
    
     15: 		if form.is_valid():
    
     16: 			# {"name":"yuan", "email":"123@qq.com"}
    
     17: 			print(form.cleaned_data)
    
     18: 		else:
    
     19: 			# {"email":"123@qq.com"}
    
     20: 			print(form.cleaned_data)
    
     21: 			# {"name":["........"]}
    
     22: 			print(form.errors)

    完整的例子:

    models.py

      1: class UserInfo(models.Model):
    
      2:     name = models.CharField(max_length=32)
    
      3:     pwd = models.CharField(max_length=32)
    
      4:     email = models.EmailField()
    
      5:     tel = models.CharField(max_length=32)

    views.py

      1: from django.shortcuts import render, HttpResponse
    
      2: # Create your views here.
    
      3: from django import forms
    
      4: class UserForm(forms.Form):
    
      5: 
    
      6:     name = forms.CharField(min_length=4)
    
      7:     pwd = forms.CharField(min_length=4)
    
      8:     r_pwd = forms.CharField(min_length=4)
    
      9:     email = forms.EmailField()
    
     10:     tel = forms.CharField()
    
     11: 
    
     12: def reg(request):
    
     13: 	
    
     14: 	if request.method=="POST":
    
     15: 
    
     16: 		form表单的属性值与forms组件字段相同,否则不会校验
    
     17: 		form = UserForm(request.POST)
    
     18: 
    
     19: 		if form.is_valid():
    
     20: 			print(form.cleaned_data)
    
     21: 		else:
    
     22: 			print(form.cleaned_data)
    
     23: 			print(form.errors)
    
     24: 
    
     25: 		return HttpResponse("OK!")
    
     26: 
    
     27: 	return render(request, "reg.html")

    reg.html

      1: <form action="" method="post">
    
      2:     {% csrf_token %}
    
      3:     <p>用户<input type="text" name="name"></p>
    
      4:     <p>密码<input type="text" name="pwd"></p>
    
      5:     <p>确认密码<input type="text" name="r_pwd"></p>
    
      6:     <p>邮箱<input type="text" name="email"></p>
    
      7:     <p>电话<input type="text" name="tel"></p>
    
      8:     <input type="submit">
    
      9: </form>

    渲染标签功能

    方法1

    views.py

      1: def...
    
      2: form = UserForm()
    
      3: 
    
      4:     return render(request, "reg.html", {"form": form, })

    reg.html

      1: <h3>forms组件渲染方式1</h3>
    
      2: <form action="" method="post">
    
      3: 
    
      4:     {% csrf_token %}
    
      5:     <p>用户名{{ form.name }}</p>
    
      6:     <p>密码{{ form.pwd }}</p>
    
      7:     <p>确认密码{{ form.r_pwd }}</p>
    
      8:     <p>邮箱{{ form.email }}</p>
    
      9:     <p>电话{{ form.tel }}</p>
    
     10:     <input type="submit">
    
     11: </form>

    其他方法

    views.py

      1: from django import forms
    
      2: class UserForm(forms.Form):
    
      3: 	name = forms.CharField(min_length=4, label="用户名")
    
      4: 	pwd = forms.CharField(min_length=4, label="密码")
    
      5: 	r_pwd = forms.CharField(min_length=4, label="确认密码")
    
      6: 	email = forms.EmailField(label="邮箱")
    
      7: 	tel = forms.CharField(label="号码")
      1: <h3>forms组件渲染方式2</h3>
    
      2: <form action="" method="post">
    
      3: 
    
      4:     {% csrf_token %}
    
      5:     {% for field in form %}
    
      6:         <div>
    
      7:             <label for="">{{ field.label }}</label>
    
      8:             {{ field }}
    
      9:         </div>
    
     10:     {% endfor %}
    
     11:     <input type="submit">
    
     12: </form>
      1: {# 不建议实际中使用,自由度简易型较低 #}
    
      2: <h3>forms组件渲染方式3</h3>
    
      3: <form action="" method="post">
    
      4:     {% csrf_token %}
    
      5:     {{ form.as_p }}
    
      6:     {{ form.as_ul }}
    
      7:     <input type="submit">
    
      8: </form>

    渲染错误信息

    views.py

      1: def reg(request):
    
      2: 
    
      3:     if request.method == "POST":
    
      4:         form = UserForm(request.POST)
    
      5: 
    
      6:         if form.is_valid():
    
      7:             print(form.cleaned_data)
    
      8:         else:
    
      9:             print(form.cleaned_data)
    
     10:             print(form.errors)
    
     11: 
    
     12:         return render(request, "reg.html", locals())
    
     13: 
    
     14:     form = UserForm()
    
     15: 
    
     16:     return render(request, "reg.html", {"form": form, })

    html

      1: <h3>forms组件错误渲染</h3>
    
      2: <form action="" method="post" novalidate>
    
      3: 
    
      4:     {% csrf_token %}
    
      5:     <p>{{ form.name.label }}
    
      6:         {{ form.name }} <span>{{ form.name.errors.0 }}</span>
    
      7:     </p>
    
      8:     <p>{{ form.pwd.label }}
    
      9:         {{ form.pwd }} <span>{{ form.pwd.errors.0 }}</span>
    
     10:     </p>
    
     11:     <p>{{ form.r_pwd.label }}
    
     12:         {{ form.r_pwd }} <span>{{ form.r_pwd.errors.0 }}</span>
    
     13:     </p>
    
     14:     <p>{{ form.email.label }}
    
     15:         {{ form.email }} <span>{{ form.email.errors.0 }}</span>
    
     16:     </p>
    
     17:     <p>{{ form.tel.label }}
    
     18:         {{ form.tel }} <span>{{ form.tel.errors.0 }}</span>
    
     19:     </p>
    
     20:     <input type="submit">
    
     21: </form>

    参数配置功能

    如果说需要将错误提示信息改成中文提示(django默认是英文)等类似的需求,就需要用到参数配置功能

    views.py

      1: from django.forms import widgets
    
      2: class UserForm(forms.Form):
    
      3: 
    
      4:     error_messages = {"required": "该字段不能为空", "invalid": "格式错误!"}
    
      5:     name = forms.CharField(min_length=4, label="用户名", error_messages=error_messages,
    
      6:                            widget=widgets.TextInput(attrs={"class": "form-control"}))
    
      7:     pwd = forms.CharField(min_length=4, label="密码", widget=widgets.PasswordInput(attrs={"class": "form-control"}),
    
      8:                           error_messages=error_messages)
    
      9:     r_pwd = forms.CharField(min_length=4, label="确认密码", widget=widgets.PasswordInput(attrs={"class": "form-control"}),
    
     10:                             error_messages=error_messages)
    
     11:     email = forms.EmailField(label="邮箱", error_messages=error_messages,
    
     12:                              widget=widgets.EmailInput(attrs={"class": "form-control"}))
    
     13:     tel = forms.CharField(label="号码", error_messages=error_messages,
    
     14:                           widget=widgets.TextInput(attrs={"class": "form-control"}))

    reg.html(需要bootstrap)

      1: <div class="container">
    
      2:     <div class="row">
    
      3:         <div class="col-md-6 col-lg-offset-3" >
    
      4: <h3>forms组件错误渲染</h3>
    
      5: <form action="" method="post" novalidate>
    
      6:     {% csrf_token %}
    
      7:     <p>{{ form.name.label }}
    
      8:         {{ form.name }} <span>{{ form.name.errors.0 }}</span>
    
      9:     </p>
    
     10:     <p>{{ form.pwd.label }}
    
     11:         {{ form.pwd }} <span>{{ form.pwd.errors.0 }}</span>
    
     12:     </p>
    
     13:     <p>{{ form.r_pwd.label }}
    
     14:         {{ form.r_pwd }} <span>{{ form.r_pwd.errors.0 }}</span>
    
     15:     </p>
    
     16:     <p>{{ form.email.label }}
    
     17:         {{ form.email }} <span>{{ form.email.errors.0 }}</span>
    
     18:     </p>
    
     19:     <p>{{ form.tel.label }}
    
     20:         {{ form.tel }} <span>{{ form.tel.errors.0 }}</span>
    
     21:     </p>
    
     22:     <input type="submit">
    
     23: </form>
    
     24:         <div>
    
     25:     <div>
    
     26: <div>

    钩子功能

    比较复杂的字段检测功能,看源码是双重校验,全局钩子校验和局部钩子校验

    局部钩子

    views.py

      1: from app01.models import UserInfo
    
      2: from django.core.exceptions import ValidationError
    
      3: 
    
      4: def...(同上)
    
      5:     # clean_%s固定写法
    
      6:     def clean_name(self):
    
      7: 
    
      8:         val = self.cleaned_data.get("name")
    
      9:         res = UserInfo.objects.filter(name=val)
    
     10:         if not res:
    
     11:             return val
    
     12:         else:
    
     13:             raise ValidationError("该用户已注册")
    
     14: 
    
     15:     def clean_tel(self):
    
     16: 
    
     17:         val = self.cleaned_data.get("tel")
    
     18:         if len(val) == 11:
    
     19:             return val
    
     20:         else:
    
     21:             raise ValidationError("手机号格式错误")
    
     22: 

    全局钩子

      1: class...
    
      2: def clean(self):
    
      3: 
    
      4:     pwd = self.cleaned_data.get("pwd")
    
      5:     r_pwd = self.cleaned_data.get("r_pwd")
    
      6:     # 为了避免同时出现两个错误(比如pwd字段检验不通过并且pwd!=r_pwd)
    
      7:     if pwd and r_pwd:
    
      8: 	    if pwd == r_pwd:
    
      9: 	        return self.cleaned_data
    
     10: 	    else:
    
     11: 	        raise ValidationError("两次密码不一致")
    
     12: 	else:
    
     13: 		return self.cleaned_data
    
     14: 
    
     15: 
    
     16: def...
    
     17: 	
    
     18: 	errors = form.errors.get("__all__")
    
     19: 

    html

      1: <p>{{ form.r_pwd.label }}
    
      2:         {{ form.r_pwd }} <span class="error">{{ form.r_pwd.errors.0 }}</span><span class="error">{{ errors.0 }}</span>
    
      3:     </p>

    最后,为了程序的解耦性,可以将钩子放到一个单独的py文件里,记得文件名不要冲突!

  • 相关阅读:
    Git的基本使用(只是基本使用)
    GET与POST的比较
    GO开发:链表
    阿里云啊
    以太坊区块和交易存储
    以太坊私有链部署合约
    以太坊go-ethereum签名部分源码解析
    GO开发:接口
    区块链开发:以太坊网络
    Go开发[八]goroutine和channel
  • 原文地址:https://www.cnblogs.com/haoqirui/p/10230500.html
Copyright © 2020-2023  润新知