form介绍

form主要功能: 页面可用的HTML标签,对用户提交的数据进行校验,保留上次输入内容

普通注册

1、html页面
reg.html
{% csrf_token %}
用户名:
密码: {{ error.pwd }}
2、urls.py urlpatterns = [ path('admin/', admin.site.urls), path('reg/', views.register), ] 3、views.py def register(request): error_msg = {"pwd": "", "username": ""} if request.method == "POST": username = request.POST.get("username") pwd = request.POST.get("pwd") if len(pwd) < 6: error_msg["pwd"] = "长度不能小于6" return render(request, "reg.html", {"error": error_msg})

python_day22_Django-6 (form)_第1张图片

使用form注册

1、html页面
{% csrf_token %} {{ form_obj.as_p }} {# 生成html页面 #} {{ form_obj.errors.pwd }} {# 打印错误提示 #}
2、 urls.py与 普通注册的一样 3、views.py from app01 import formd def register2(request): form_obj = formd.RgeForm() if request.method == "POST": form_obj = formd.RgeForm(request.POST) # django自动生成的 html页面 print(form_obj) #
  • This field is required.
return render(request, "reg2.html", {"form_obj": form_obj}) 4、formd.py 在项目中创建一个formd.py文件 from django import forms # 引用forms模块 # 创建注册函数 class RgeForm(forms.Form): name = forms.CharField( label="用户名", max_length=16, # 最大长度以及错误提示 error_messages={ "max_length": "最大长度16" } ) pwd = forms.CharField( label="密码", min_length=6, error_messages={ "required": "不能为空", "invalid": "格式错误", "min_length": "最少6位", } )

form的功能: 来源: https://www.cnblogs.com/liwenzhou/p/8747872.html
• 前端页面是form类的对象生成的 -->生成HTML标签功能
• 当用户名和密码输入为空或输错之后 页面都会提示 -->用户提交校验功能
• 当用户输错之后 再次输入 上次的内容还保留在input框 -->保留上次输入内容

1.1、error_messages

错误重写

        error_messages={ 
            "required": "不能为空",    # 当请求为空时提示
            "invalid": "格式错误",       # 格式错误
            "min_length": "最少6位",  # 最小长度
            "max_length":" 最大N位"  # 最大长度
        }

1.2、password

    pwd = forms.CharField(
        label="密码",
        min_length=6,
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "最少6位",
        },
        # widget=forms.widgets.PasswordInput()     # 插件widgets
    )

不加 widget=forms.widgets.PasswordInput()
python_day22_Django-6 (form)_第2张图片
加上widget=forms.widgets.PasswordInput()
python_day22_Django-6 (form)_第3张图片

增加类

    pwd = forms.CharField(
        label="密码",
        min_length=6,
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "最少6位",
        },
        widget=forms.widgets.PasswordInput(
            attrs={"class":"ap1"}
        )
    )

python_day22_Django-6 (form)_第4张图片

1.3选择框

choices 单选框

    hobby221 = forms.ChoiceField(
        choices=((1,"吃饭"), (2,"睡觉"),(3,"做梦"),),
        label="爱好",
        initial=1,
        widget=forms.widgets.Select()
    )

python_day22_Django-6 (form)_第5张图片

MultipleChoiceField 多选框

    hobby2 = forms.MultipleChoiceField(
        choices=((1, "吃饭"), (2, "睡觉"), (3, "做梦"),),
        label="多选爱好",
        initial=3,    # 初始化选择框
        widget=forms.widgets.SelectMultiple()
    )

python_day22_Django-6 (form)_第6张图片

单选CheckboxInput

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

python_day22_Django-6 (form)

多选框 CheckboxSelectMultiple

    keep2 = forms.MultipleChoiceField(
        choices=((1, "吃饭"), (2, "睡觉"), (3, "做梦"),),
        label="多选爱好",
        initial="checked",    # 初始化选择框
        widget=forms.widgets.CheckboxSelectMultiple()
    )

css中可以直接去掉li的点

python_day22_Django-6 (form)_第7张图片

2、实例

2.1、实例(form简化版注册)

1、Html页面
    
{% csrf_token %}
{{ form_obj.name }} {{ form_obj.name.errors.0 }}
{{ form_obj.passwd }} {{ form_obj.passwd.errors.0 }}
2、urls.py urlpatterns = [ path("reg/", views.reg), ] 3、html_form.py 在应用下创建html_form.py文件 # 导入模块,并且继承引用 from django import forms class RegForm(forms.Form): name = forms.CharField( label="帐号:", min_length=6, error_messages={ "min_length": "最小长度为6", "required": "输入不能为空", }, widget=forms.widgets.Input( attrs=({"class":"form-control"}) ) ) passwd = forms.CharField( label="密码", min_length=6, max_length=16, error_messages={ "min_length": "最小长度为6", "max_length": "超过最大长度", "required": "输入不能为空", }, widget=forms.widgets.PasswordInput( attrs=({"class":"ap1 form-control"}) ), ) 4、models.py文件 创建一个用户注册使用的数据库 from django.db import models # Create your models here. class UserRegister(models.Model): name = models.CharField(max_length=16, unique=True, null=False) passwd = models.CharField(max_length=16, null=False) 控制台下使用 python manage.py makemigrations python manage.py migrate 创建数据库 5、views.py 视图函数 from django.shortcuts import render, redirect, HttpResponse from login.html_forms import RegForm from login import models def reg(request): form_obj = RegForm() # 初始化类 if request.method == "POST": # 当它是post时才执行这个 form_obj = RegForm(request.POST) if form_obj.is_valid(): # 当输入的检验通过时才继续往下执行 # cleaned_data (当校验通过时forms字典,类似于各种request.POST.get("xxxxxx")) form_register_list = form_obj.cleaned_data # 获取用户是否存在数据库中,如果存在就返回注册界面,如果不存在就创建 ret = models.UserRegister.objects.filter(name=form_register_list.get("name")) print(ret) if ret: return redirect("/reg/") else: models.UserRegister.objects.create(**form_register_list) return HttpResponse("注册成功") return render(request, "reg.html", {"form_obj": form_obj})

python_day22_Django-6 (form)_第8张图片
python_day22_Django-6 (form)_第9张图片
python_day22_Django-6 (form)_第10张图片

2.2、校验判断用户及密码

1、html页面
{% csrf_token %}
{{ form_obj.name }} {{ form_obj.name.errors.0 }}
{{ form_obj.pwd }} {{ form_obj.pwd.errors.0 }}
{{ form_obj.re_pwd }} {{ form_obj.re_pwd.errors.0 }}
2、urls.py 不变 3、html_forms.py #!/usr/bin/env python # -*- coding:utf-8 -*- from django import forms from login import models from django.core.exceptions import ValidationError class RegForm(forms.Form): name = forms.CharField( label="帐号:", min_length=6, error_messages={ "min_length": "最小长度为6", "required": "输入不能为空", }, widget=forms.widgets.Input( attrs=({"class": "form-control"}) ) ) pwd = forms.CharField( label="密码", min_length=6, max_length=16, error_messages={ "min_length": "最小长度为6", "max_length": "超过最大长度", "required": "输入不能为空", }, widget=forms.widgets.PasswordInput( attrs=({"class":"form-control"}), # 失败不清空 render_value=True, ), ) re_pwd = forms.CharField( label="确认密码", min_length=6, max_length=16, error_messages={ "min_length": "最小长度为6", "max_length": "超过最大长度", "required": "输入不能为空", }, widget=forms.widgets.PasswordInput( attrs=({"class":" form-control"}), render_value=True, ), ) # 钩子函数,调用hasattr反射函数 def clean_name(self): name = self.cleaned_data.get("name") ret = models.UserRegister.objects.filter(name=name) if ret: raise ValidationError("用户已存在") return name # 钩子函数, 获取两次密码,并让它相比较 def clean(self): pwd = self.cleaned_data.get("pwd") re_pwd = self.cleaned_data.get("re_pwd") print(self.cleaned_data) if pwd != re_pwd: # 如果不添加add_error那么 print(form.error)
  • __all__
    • 二次密码不一致
self.add_error("pwd", ValidationError("两次密码不一致")) raise ValidationError("二次密码不一致") return self.cleaned_data 4、view.py from django.shortcuts import render, redirect, HttpResponse from login.html_forms import RegForm from login import models # Create your views here. def cz_login(request): print(request.GET) return render(request, "index.html") def reg(request): form_obj = RegForm() if request.method == "POST": form_obj = RegForm(request.POST) # 实例化将数据输入 if form_obj.is_valid(): form_register_list = form_obj.cleaned_data form_register_list.pop("re_pwd") models.UserRegister.objects.create(**form_register_list) return HttpResponse("注册成功") print(form_obj.errors) return render(request, "reg.html", {"form_obj": form_obj})

最终效果
python_day22_Django-6 (form)_第11张图片

2.3、使用form提交的大致完整注册界面

目录文件
python_day22_Django-6 (form)_第12张图片

1、settings.py
# 静态文件定义
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
]

# auth扩展模块,如果手动定义需要增加这个
AUTH_USER_MODEL = 'app01.UserInfo'

2、formd.py   定义forms 生成html页面
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from django import forms
from app01 import models
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError

class RgeForm(forms.Form):
    username = forms.CharField(
        label="用户名",
        max_length=16,
        error_messages={
            "required": "帐号不能为空",
            "max_length": "最大长度16",
        },
        widget=forms.widgets.Input(
            attrs={
                "class": "form-control",
            }
        )
    )

    password = forms.CharField(
        label="密码",
        min_length=6,
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "最少6位",
        },
        widget=forms.widgets.PasswordInput(
            attrs={
                "class":"form-control",
            },
            render_value=True,   # 密码如果输入错误,不清空
        )
    )

    re_password = forms.CharField(
        label="确认密码",
        min_length=6,
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "最少6位",
        },
        widget=forms.widgets.PasswordInput(
            attrs={
                "class":"form-control",
            },
            render_value=True,
        )
    )

    phone = forms.CharField(
        label="手机号码",
        min_length=11,
        max_length=11,
        validators=[RegexValidator(r'^[1][1-9]+$',"格式错误")],
        error_messages={
            "required": "不能为空",
            # "invalid": "格式错误",
            "min_length": "最少11位",
            "max_length": "最大11位",
        },
        widget=forms.widgets.TextInput(
            attrs={
                "class":"form-control",
            }
        )
    )

    email = forms.CharField(
        label="邮箱",
        min_length=11,
        max_length=11,
        error_messages={
          "required": "不能为空",
        },
        widget=forms.widgets.TextInput(
            attrs={
                "class":"form-control",
            }
        )
    )

    # 判断密码是否一致, 如果不一致增加错误提示
    def clean(self):
        password = self.cleaned_data.get("password")
        re_password = self.cleaned_data.get("re_password")
        if password != re_password:
            self.add_error("password","二次密码不一致")
            raise ValidationError("二次密码不一致")
        return self.cleaned_data

    # 判断用户是否存在
    def clean_username(self):
        username = self.cleaned_data.get("username")
        ret = models.UserInfo.objects.filter(username=username)
        if ret:
            self.add_error("username","用户已存在")
            raise ValidationError("用户已存在")
        return username

3、html页面     reg2.html

    
    reg
    
    



{% csrf_token %}
{{ form_obj.username }} {{ form_obj.username.errors.0 }}
{{ form_obj.password }} {{ form_obj.password.errors.0 }}
{{ form_obj.re_password }} {{ form_obj.password.errors.0 }}
{{ form_obj.phone }} {{ form_obj.phone.errors.0 }}
{{ form_obj.email }} {{ form_obj.email.errors.0 }}
4、views.py from django.shortcuts import render, redirect, HttpResponse from app01 import formd from app01 import models # Create your views here. def register2(request): form_obj = formd.RgeForm() if request.method == "POST": form_obj = formd.RgeForm(request.POST) # django自动生成的 html页面 print(form_obj) #
  • This field is required.
if form_obj.is_valid(): # 如果返回true就继续执行 form_userinfo_list = form_obj.cleaned_data form_userinfo_list.pop("re_password") models.UserInfo.objects.create_user(**form_userinfo_list) return HttpResponse("用户注册成功") return render(request, "reg2.html", {"form_obj": form_obj}) 5、models.py from django.db import models from django.contrib.auth.models import AbstractUser # Create your models here. class UserInfo(AbstractUser): """ 用户扩展表 """ phone = models.CharField(max_length=11, null=True) # 允许为空 addr = models.CharField(max_length=200, null=True) def __str__(self): return self.phone

python_day22_Django-6 (form)_第13张图片

MVC 说明
python_day22_Django-6 (form)_第14张图片
MTV 说明
python_day22_Django-6 (form)_第15张图片
python_day22_Django-6 (form)_第16张图片

FAQ

在settings.py中修改  
LANGUAGE_CODE = "zh-hans"   后台会显示为中文 当时间会提前8小时
\# TIME_ZONE = 'UTC'   将UTC修改成上海时间就能解决
TIME_ZONE='Asia/Shanghai'