Django Form表单

本文深入探讨Django框架中的表单模块,介绍其如何简化HTML表单的创建与处理,涵盖Form对象、Field类、Widget组件及常用属性方法,通过实例演示数据验证与表单渲染。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Form表单

概要

通常情况下,我们需要自自己手动在HTML页面面中,编写form标签和其内的其它元
素。但这费时费力力力,而而且有可能写得不不太恰当,数据验证也比比较麻烦。有鉴于此,Django在内部集成了一个表单模块,专门帮助我们快速处理理表单相关的内容。Django的表单模块给我们提供了了下面面三个主要功能:

  1. 准备和重构数据用于页面面渲染
  2. 为数据创建HTML表单元素
  3. 接收和处理理用用户从表单发送过来的数据

Form相关的对象包括

  • Widget:用用来渲染成HTML元素的部件,如:forms.Textarea对应HTML中的:
    ‘textarea’ 标签

  • Field:Form对象中的一个字段,如:EmailField表示email字段,如果这个字段不不是有效的Email地址格式,就会产生生错误。

  • Form:一系列列Field对象的集合,负责验证和显示HTML元素

  • Form Media:用用来渲染表单的CSS和JavaScript资源。

基本使用

1、使用

Form对象封装了一系列列Field和验证规则,Form类都必须直接或间接继承自django.forms.Form,定义Form有两种方方式:

  • 直接继承Form

    class XXXForm(forms.Form):
    pass
    
  • 结合Model,继承django.forms.ModelForm

    class XXX(models.Model):
    	字段 = models.CharField(max_length=30)
    	字段 = models.CharField(max_length=20)
    class XXXForm(ModelForm):
    	class Meta:
    		model = XXX
    		field = ('字段', '字段')
    # 只显示model中指定的字段
    

2、示例代码

  • models
class Shop(models.Model):
	title = models.CharField('标题', max_length=30)
	content = models.CharField('内容', max_length=20)
class Meta:
	db_table = 'T_SHOP'
  • ModelForm

    class ShopForm(ModelForm):
    	class Meta:
    		model = models.Shop
    		fields = ('title', 'content')# 只显示model中指定的字段
    
  • views

    from django.shortcuts import render
    # Create your views here.
    from .forms import ShopForm
    def add_shop(request):
    	if request.method == "POST":
    	form = ShopForm(request.POST)
    	if form.is_valid():
    	# 所有验证都通过
    	# 处理理表单数据
    	title = form.cleaned_data['title']
    	print(title)
    	# content = form.cleaned_data['content']# 保存数据
    	form.save()
    	return render(request, 'shop/add_shop.html',
    {"shop_form": form})
    	else:
    		form = ShopForm()
    		return render(request, 'shop/add_shop.html', {"shop_form":
    form})
    
  • 模板中使用

    <form action="{% url 'add' %}" method="post">
    	{% csrf_token %}
    	{{ shop_form }}
    	<input type="submit" value="提交"/>
    </form>
    

常用的Field类

  1. 核心字段参数

    参数名说明
    required给字段添加必填属性,不不能空着,若要表示一个字段不是必需的,设置required=False
    labellabel参数用用来给字段添加‘人人类友好’的提示信息。如果没有设置这个参数,那么就用用字段的首首字母大写名字
    label_suffixDjango默认为上面面的label参数后面面加个冒号后缀,如果想自自定义,可以使用用label_suffix 参数
    initial为HTML页面面中表单元素定义初始值。也就是input元素的value参数的值
    widget指定渲染Widget时使⽤的widget类,也就是这个form字
    widget指定渲染Widget时使用用的widget类,也就是这个form字段在HTML⻚页面面中是显示为文文本输入入框?密码输入入框?单
    help_text该参数用用于设置字段的辅助描述文文本
    error_messages该参数允许你覆盖字段引发异常时的默认信息。 传递的是一个字典,其值为你想覆盖的错误信息
    validators指定一个列列表,其中包含了了为字段进行行行验证的函数
    localizelocalize参数帮助实现表单数据输入入的本地化
    disabled设置有该属性的字段在前端页面中将显示为不可编辑状态
    • 核心心字段
BooleanField默认的Widget:CheckboxInput 空值:Flase 规范:Python 的True 或 False。错误信息的键:required
FileField
ModelChoiceField
IntergerField
CharField
ChoiceField
DateField
DateTimeFiled
DecimalField
FloatField
EmailField
ImageField
  • Form常用的属性和方法

    cleaned_data(字典)表单中通过验证的数据form.cleaned_data.get(‘username’)
    changed_data有变换的字段列表form.change_data
    fields表单中字段属性
    is_bound是否绑定
    is_valid()是否通过验证
    errors错误信息
    has_changed()表单数据是否已从初始状态数据更改
    errors.as_json(escape_html)=Flase返回json序列化后的错误信息字典
  • 示例代码

    • forms
    # 用户表单
    class UserForm(forms.Form):
        username = forms.CharField(label='用户名',min_length=3,max_length=30,
                                   error_messages={
                                       'required':'必填',
                                       'min_length':'最少3个字符',
                                       'max_length': '最多30字符',
                                   })
        password_hash = forms.CharField(label='密码',validators=[check_password],min_length=6,max_length=128,widget=forms.PasswordInput(),error_messages={
            'required': '必填',
            'min_length': '最少6个字符',
            'max_length': '最多128字符',
        })
        confirm_password = forms.CharField(label='确认密码',min_length=6,max_length=128,widget=forms.PasswordInput(),error_messages={
            'required': '必填',
            'min_length': '最少6个字符',
            'max_length': '最多128字符',
        })
        sex = forms.ChoiceField(label='性别',choices=[(0,'女'),(1,'男'),(2,'保密')],initial=1,widget=forms.RadioSelect, required=False)
        address = forms.ChoiceField(label='家庭住址',choices=[(1,'北京'),(2,'上海'),(3,'广州'),(4,'深圳')])
        email = forms.EmailField(label='邮箱',required=False,error_messages={
            'invalid':"邮箱格式无效"
        })
        phone = forms.CharField(label='电话',min_length=11,required=False,error_messages={
            'min_length':'至少11位'
        })
        regtime = forms.DateField(label='注册日期',required=False,error_messages={
            'invalid':'日期格式错误'
        })
        usertype = forms.ChoiceField(label='用户类型',choices=[(1,'普通用户'),(2,'管理员')],required=False,initial=1)
    
    
    • views

      def index(request):
          return HttpResponse("首页")
      
      
      def add(request):
          form = StudentForm()  #空的表单,没有数据
          if request.method == 'POST':
              form = StudentForm(request.POST)
              if form.is_valid():  #验证通过
                  print(form.cleaned_data)
                  name = form.cleaned_data.get('name')
                  sex = form.cleaned_data.get('sex')
                  age = form.cleaned_data.get('age')
                  #写入数据库
                  Stuent.objects.create(**form.cleaned_data)
                  #验证成功跳转到首页
                  return redirect(reverse('index'))
          # return render(request,'add.html',context={'form':form})
          # return render(request,'add1.html',context={'form':form})
          # return render(request,'add2.html',context={'form':form})
          return render(request,'add3.html',context={'form':form})
      
      
      def register(request):
          form = UserForm()
          if request.method == 'POST':
              print(request.POST)
              form = UserForm(request.POST)
              if form.is_valid():
                  del form.cleaned_data['confirm_password']
                  value = form.cleaned_data['password_hash']
                  form.cleaned_data['password_hash'] = hashlib.sha1(value.encode('utf8')).hexdigest()
                  print(form.cleaned_data)
                  User.objects.create(**form.cleaned_data)
                  return redirect(reverse('index'))
      
          return render(request,'register.html',context={'form':form})
      
      
      def example(request):
          form = Example()
          if request.method == 'POST':
              form = Example(request.POST)
              if form.is_valid():
                  print(form.cleaned_data)
                  return redirect(reverse('index'))
          return render(request,'example.html')
      
      
      • html

        
        <form action="/add/" method="post">
            {% csrf_token %}
            <div>
                <label for="{{ form.name.id_for_label }}">{{ form.name.label_tag }}</label>
                {{ form.name }}
                {{ form.name.errors }}
            </div>
             <div>
                <label for="{{ form.sex.id_for_label }}">{{ form.sex.label_tag }}</label>
                {{ form.sex }}
                {{ form.sex.errors }}
            </div>
            <div>
                <label for="{{ form.age.id_for_label }}">{{ form.age.label_tag }}</label>
                {{ form.age }}
                {{ form.age.errors }}
            </div>
            <input type="submit">
        </form>
        
        
        
        

#register

  <form action="/register/" method="post">
     {% csrf_token %}
{#    {% include 'renderform.html' %}#}
    {# 渲染隐藏字段 #}
    {% for hidefield in form.hidden_fields %}
        {{ hidefield }}
    {% endfor %}
    {# 渲染可视字段  #}
    {% for field in form.visible_fields %}
        {% if field.html_name == 'sex' %}
            {{ field.label_tag }}
            {% for radio in form.sex %}
                {{ radio.label_tag }}
                {{ radio.tag }}
                {{ radio.choice_label }}
            {% endfor %}
        {% else %}
        <div>
            {{ field.label_tag }}
            {{ field }}
            {{ field.errors }}
        </div>
        {% endif %}
    {% endfor %}
{#    {% for radio in form.sex %}#}
{#        {{ radio.label_tag }}#}
{#        {{ radio.tag }}#}
{#        {{ radio.choice_label }}#}
{#    {% endfor %}#}

    <input type="submit">
</form>

重写验证

  • 注意
    • 函数名必须为clean_字段名
    • 必须有返回值
    • 只能拿自己当前的字段值

示例代码

  • 验证单个字段
def check_password(value):
    if re.match(r'\d+$',value):
        raise ValidationError("密码不能是纯数字")
        
  • 类方法实现

      class UserForm(forms.Form):
            def clean_phone(self):
            	value = self.cleaned_data.get('phone')
            	if not re.match(r"^1[35678]\d{9}$", value):
               	 	raise ValidationError("手机号码不正确,请重新填写")
            	else:
               	 	return value
    
  • 验证两个变单数据的一致

     def clean(self):
    
            password1 = self.cleaned_data.get("password_hash")
    
            password2 = self.cleaned_data.get("confirm_password")
            print(password1,password2)
            if password1 != password2:
                raise ValidationError("两次密码不一致")
            else:
                return self.cleaned_data
    
    

    **注意事项:**对于

    标签中
    {{ form.as_ul }} 将它们渲染在

  • 标签中
    注意,你必须自自己己提供 或
    • 元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值