FORM表单

FORM简介我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来。与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否

大家好,又见面了,我是你们的朋友全栈君。

FORM简介

我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来。

与此同时我们在好多场景下都需要对用户的输入做校验,比如校验用户是否输入,输入的长度和格式等正不正确。如果用户输入的内容有错误就需要在页面上相应的位置显示显示对应的错误信息.。

Django form组件就实现了上面所述的功能。

总结一下,其实form组件的主要功能如下:

生成页面可用的HTML标签
对用户提交的数据进行校验
保留上次输入内容

普通的登陆

views.py

def login(request):
    error_msg = ""
    if request.method == "POST":
        username = request.POST.get("username")
        pwd = request.POST.get("pwd")
        if username == "Q1mi" and pwd == "123456":
            return HttpResponse("OK")
        else:
            error_msg = "用户名或密码错误"
    return render(request, "login.html", {"error_msg": error_msg})

login.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>login</title>
  <style>
    .error {
      color: red;
    }
  </style>
</head>
<body>
<form action="/login/" method="post">
  {% csrf_token %}
  <p>
    <label for="username">用户名</label>
    <input type="text" name="username" id="username">
  </p>
  <p>
    <label for="pwd">密码</label>
    <input type="password" name="pwd" id="pwd">
    <span class="error"></span>
  </p>
  <p>
    <input type="submit">
    <span class="error">{{ error_msg }}</span>
  </p>
</form>
</body>
</html>

form组件登陆

views.py

先定义好一个LoginForm类。

class LoginForm(forms.Form):
    username = forms.CharField(min_length=8, label="用户名")
    pwd = forms.CharField(min_length=6, label="密码")


def login2(request):
    error_msg = ""
    form_obj = LoginForm()
    if request.method == "POST":
        form_obj = LoginForm(request.POST)
        if form_obj.is_valid():
            username = form_obj.cleaned_data.get("username")
            pwd = form_obj.cleaned_data.get("pwd")
            if username == "Q1mi" and pwd == "123456":
                return HttpResponse("OK")
            else:
                error_msg = "用户名或密码错误"
    return render(request, "login2.html", {"form_obj": form_obj, "error_msg": error_msg})

login2.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>login</title>
  <style>
    .error {
      color: red;
    }
  </style>
</head>
<body>
<form action="/login2/" method="post" novalidate>
  {% csrf_token %}
  <p>
    {{ form_obj.username.label }}
    {{ form_obj.username }}
    <span class="error">{{ form_obj.username.errors.0 }}</span>
  </p>
  <p>
    {{ form_obj.pwd.label }}
    {{ form_obj.pwd }}
    <span class="error">{{ form_obj.pwd.errors.0 }}</span>
  </p>
  <p>
    <input type="submit">
    <span class="error">{{ error_msg }}</span>
  </p>
</form>
</body>
</html>

看网页效果发现 也验证了form的功能:
• 前端页面是form类的对象生成的                                      –>生成HTML标签功能
• 当用户名和密码输入为空或输错之后 页面都会提示        –>用户提交校验功能
• 当用户输错之后 再次输入 上次的内容还保留在input框   –>保留上次输入内容

FORM常用字段

initial

初始值,input框里面的初始值。

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用户名",
        initial="张三"  # 设置默认值
    )
    pwd = forms.CharField(min_length=6, label="密码")

error_messages

重写错误信息。

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用户名",
        initial="张三",
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "用户名最短8位"
        }
    )
    pwd = forms.CharField(min_length=6, label="密码")

password

class LoginForm(forms.Form):
    ...
    pwd = forms.CharField(
        min_length=6,
        label="密码",
        widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
    )

radioSelect

单radio值为字符串

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用户名",
        initial="张三",
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "用户名最短8位"
        }
    )
    pwd = forms.CharField(min_length=6, label="密码")
    gender = forms.fields.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性别",
        initial=3,
        widget=forms.widgets.RadioSelect
    )

单选Select

class LoginForm(forms.Form):
    ...
    hobby = forms.fields.ChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
        label="爱好",
        initial=3,
        widget=forms.widgets.Select
    )

多选Select

class LoginForm(forms.Form):
    ...
    hobby = forms.fields.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.SelectMultiple
    )

单选checkbox

class LoginForm(forms.Form):
    ...
    keep = forms.fields.ChoiceField(
        label="是否记住密码",
        initial="checked",
        widget=forms.widgets.CheckboxInput
    )

多选checkbox

class LoginForm(forms.Form):
    ...
    hobby = forms.fields.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple
    )

关于choice的注意事项

在使用选择标签时,需要注意choices的选项可以从数据库中获取,但是由于是静态字段 ***获取的值无法实时更新***,那么需要自定义构造方法从而达到此目的。

方式一:

from django.forms import Form
from django.forms import widgets
from django.forms import fields

 
class MyForm(Form):
 
    user = fields.ChoiceField(
        # choices=((1, '上海'), (2, '北京'),),
        initial=2,
        widget=widgets.Select
    )
 
    def __init__(self, *args, **kwargs):
        super(MyForm,self).__init__(*args, **kwargs)
        # self.fields['user'].widget.choices = ((1, '上海'), (2, '北京'),)
        # 或
        self.fields['user'].widget.choices = models.Classes.objects.all().values_list('id','caption')

方式二:

from django import forms
from django.forms import fields
from django.forms import models as form_model

 
class FInfo(forms.Form):
    authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all())
    # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())

校验

方式一:

from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator
 
class MyForm(Form):
    user = fields.CharField(
        validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
    )

方式二:

import re
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.exceptions import ValidationError
 
 
# 自定义验证规则
def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手机号码格式错误')
 
 
class PublishForm(Form):
 
 
    title = fields.CharField(max_length=20,
                            min_length=5,
                            error_messages={'required': '标题不能为空',
                                            'min_length': '标题最少为5个字符',
                                            'max_length': '标题最多为20个字符'},
                            widget=widgets.TextInput(attrs={'class': "form-control",
                                                          'placeholder': '标题5-20个字符'}))
 
 
    # 使用自定义验证规则
    phone = fields.CharField(validators=[mobile_validate, ],
                            error_messages={'required': '手机不能为空'},
                            widget=widgets.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'手机号码'}))
 
    email = fields.EmailField(required=False,
                            error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'},
                            widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'}))

FORM应用BootStrap样式

<span role="heading" aria-level="2">FORM表单
<span role="heading" aria-level="2">FORM表单

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="x-ua-compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
  <title>login</title>
</head>
<body>
<div class="container">
  <div class="row">
    <form action="/login2/" method="post" novalidate class="form-horizontal">
      {% csrf_token %}
      <div class="form-group">
        <label for="{{ form_obj.username.id_for_label }}"
               class="col-md-2 control-label">{{ form_obj.username.label }}</label>
        <div class="col-md-10">
          {{ form_obj.username }}
          <span class="help-block">{{ form_obj.username.errors.0 }}</span>
        </div>
      </div>
      <div class="form-group">
        <label for="{{ form_obj.pwd.id_for_label }}" class="col-md-2 control-label">{{ form_obj.pwd.label }}</label>
        <div class="col-md-10">
          {{ form_obj.pwd }}
          <span class="help-block">{{ form_obj.pwd.errors.0 }}</span>
        </div>
      </div>
      <div class="form-group">
      <label class="col-md-2 control-label">{{ form_obj.gender.label }}</label>
        <div class="col-md-10">
          <div class="radio">
            {% for radio in form_obj.gender %}
              <label for="{{ radio.id_for_label }}">
                {{ radio.tag }}{{ radio.choice_label }}
              </label>
            {% endfor %}
          </div>
        </div>
      </div>
      <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
          <button type="submit" class="btn btn-default">注册</button>
        </div>
      </div>
    </form>
  </div>
</div>

<script src="/static/jquery-3.2.1.min.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
</body>
</html>

View Code

批量添加样式

可通过重写form类的init方法来实现。

<span role="heading" aria-level="2">FORM表单
<span role="heading" aria-level="2">FORM表单

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用户名",
        initial="张三",
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "用户名最短8位"
        }
    ...

    def __init__(self, *args, **kwargs):
        super(LoginForm, self).__init__(*args, **kwargs)
        for field in iter(self.fields):
            self.fields[field].widget.attrs.update({
                'class': 'form-control'
            })

View Code

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/124463.html原文链接:https://javaforall.net

(0)
上一篇 2022年3月29日 下午7:35
下一篇 2022年3月29日 下午7:35


相关推荐

  • c#窗体怎么居中_窗口居中

    c#窗体怎么居中_窗口居中窗体始终居桌面中央显示,需要考虑以下两个方面:(1).窗体距离桌面左部边缘与桌面的宽度以及自身宽度的判断;(2).窗体距离桌面上边缘与桌面的高度以及自身高度的判断下面用代码一一实现,当然这都是在窗体加载时完成this.Left=Screen.PrimaryScreen.Bounds.Width/2-this.Width/2;//桌面的宽度的一半减去自身宽的的一半this…….

    2025年10月14日
    7
  • 树莓派简单教程(一)「建议收藏」

    树莓派简单教程(一)「建议收藏」一、什么是树莓派基于ARM的微型电脑主板,其系统基于linux二、树莓派能做什么2.1挖矿【树莓派:居然拿我干这事?———6分钟使用树莓派,编译CPU挖矿程序测试算力。-哔哩哔哩】https://b23.tv/tvx06lM…

    2022年10月14日
    4
  • 了解ACL—通配符掩码「建议收藏」

    了解ACL—通配符掩码「建议收藏」学习ACL,搞懂ACL就不能不搞定wildcardmask,通配符掩码。说简单点,通配符掩码就是0为绝对匹配,必须严格匹配才行,而1为任意,从某种意义上讲,如果一个8位上有一个1字符,那也只有两种方式,0或者1,但是如果进行组合,那么方式就多了。举例说明吧。一般我们在应用上都是进行地址块的匹配,怎么讲呢?就是说:1)对某个ABC类网进行匹配或者教通配符屏蔽2)对某个子网应用ACL。…

    2022年7月19日
    11
  • 什么是AI智能体(agent)?一文读懂AI智能体:定义、分类与应用,程序员必备收藏指南!

    什么是AI智能体(agent)?一文读懂AI智能体:定义、分类与应用,程序员必备收藏指南!

    2026年3月12日
    1
  • Kafka Streams实战-开发入门

    Kafka Streams实战-开发入门本文会介绍 KafkaStreams KafkaStreams 的 HelloWorld 例子 深入探索基于 KafkaStreams 的 ZMart 应用程序 把输入流拆分为多个流 1 StreamsAPIsK 有两类流 APIs low levelProcess 和 high levelStreams 本文介绍的是后者 DSL 它的核心是 KStrea

    2025年10月8日
    7
  • mysql 1062_mysql error:1062问题解决方法

    mysql 1062_mysql error:1062问题解决方法我将 id 的 int 类型改成了 bigint 就可以了 其实再改回来可能也会好了 可能是数据库备份的时候出现了错误 开发的网站后台系统在测试过程中出现了这个问题 InvalidQuery Duplicateent 127 forkey1SQLis INSERTINTO kq news Title Author Type Content IsDel A

    2026年3月26日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号