HTML与Django的form表单和表单验证详解

html的form表单

django中,前端如果要提交一些数据到views里面去,需要用到 html里面的form表单。

例如:

 # form2/urls.py

1 from django.contrib import admin
2 from django.urls import path,re_path
3 from django.conf.urls import include
4 from . import views
5 urlpatterns = [
6     re_path(r'^home$', views.home),
7     re_path(r'^login$', views.login),
8 ]

# views.py

from django.shortcuts import render,HttpResponse
def login(request):
    return render(request, 'form2/login.html')

# login.htm

1 <form action="/form2/home" method="post">   #向这个页面发送post请求,action配置目标地址
2     <p>用户名:<input type="text" name="username"></p>  #name表示key,value等于input输入的内容
3     <input type="submit" value="提交"> 
4 </form>

第二种方法: 使用url_name

1 login.html  <form action="{% url 'homepage' %}" method="post">           
2 
3 app.urls
4 
5 urlpatterns = [
6     re_path(r'^home$', views.home,name='homepage'),    #url命名 
7     re_path(r'^login$', views.login),
8 ]
View Code
第三种方法:使用namespace命名空间 (作用:当有多个app.urls时,如果存在重复的name,容易引起混乱,这时候需要引入namespace)
 1 login.html      action="{% url 'app_name:url_name' param %}"       #param参数,没有就不写
 2 
 3 <form action="{% url 'app_form2:homepage' %}" method="post">
 4 
 5 根urls
 6 
 7 path('form2/', include('form2.urls',namespace='aaaa')), #namespace必须有值,值好像可随便取~
 8 
 9 app.urls
10 
11 app_name = 'app_form2'     #django2.0之后必须写此项,否则会报错
12 urlpatterns = [
13     re_path(r'^home$', views.home, name='homepage'),   #url_name       
View Code

# form2/views.py

1 from django.shortcuts import render,HttpResponse
2 def login(request):
3     return render(request, 'form2/login.html')
4 def home(request):
5     username = request.POST.get('username') or 'lily'  #前端form表单传过来的username数据,如果为空则默认为'lily'
6     return render(request, 'form2/homepage.html', {"username":username})  #将username传给homepage.html

# homepage.html

<body>
welcome, {{username}}!   # views传过来的username变量
</body>

访问 http://127.0.0.1:8000/form2/login.提交之后,login页面会跳转到/form2/home页面

Django的form表单

主要作用是1,生成html标签,2,表单验证。

  #  新建forms.py ,定义表单字段类型

from django import  forms
class Person_Info(forms.Form):
    name = forms.CharField(max_length=4)  # 字符串类型,最长不超过4个字符
    birthday = forms.DateField()         #日期类型
    email = forms.EmailField(required=False)  # required=False表示可以为空,默认是True,不能为空
    phone = forms.IntegerField()         #数值类型

#  views.py

from django.shortcuts import render,HttpResponse
from .forms import Person_Info  #导入form表单
def person(request):
    person_obj = Person_Info()  # 创建了这个对象
    return render(request,'form2/info.html',{'obj':person_obj})  #然后把对象传给html

 info.html

<form action=""  method="post">
    {% csrf_token %}   # django自带的csrf验证,不加提交时会报错
    {{ obj }}     # views传的对象, 可以自动创建html标签
    <div>姓名:{{ obj.name }}</div>     # 也可以单独取对象中的某一个字段
    <!--<div>生日:{{ obj.birthday }}</div>-->
    <!--<div>邮箱:{{ obj.email }}</div>-->
    <!--<div>手机号:{{ obj.phone}}</div>-->
    <input type="submit" value="提交">
</form>

 csrf_token如果不加上,提交表单会报错

或者在settings里面注释掉'django.middleware.csrf.CsrfViewMiddleware'。

访问 http://127.0.0.1:8000/form2/info可以看到生成的表单。体现了django的form的第一个作用,即自动生成html标签,如下:

 

 填入数据的时候,如果数据不合法,就会有提示。

 这样在后端就可以验证,如果字段合法,就获取数据操作,如果不合法,就返回错误信息。

验证用户输入

 views.py

from django.shortcuts import render
from .forms import Person_Info
def person(request):
    form_obj = Person_Info()
    if request.method == 'POST':   #获取用户输入
        print("request.POST:", request.POST)  
        form_obj = Person_Info(request.POST) #将post过来的数据当做参数传给Person_Info这个form表单,将name,birthday,email等封装到form_obj,判断输入是否合法
        print("form is valid:", form_obj.is_valid())  # 通过is_valid()方法判断表单数据是否合法
    return render(request, 'form2/info.html', {"obj": form_obj})

 这里我输入一个不合法的birthday,可以看到:

 

增加一个判断,如果填写的表单正确,返回表单数据,如果不合法,返回错误信息。

from django.shortcuts import render,HttpResponse
from .forms import Person_Info
def person(request):
    form_obj = Person_Info()
    if request.method == 'POST':
        form_obj = Person_Info(request.POST)
        if form_obj.is_valid():
            print("form is valid ^_^** ", form_obj.cleaned_data)  # 返回表单数据,是字典形式
            username = form_obj.cleaned_data.get('name')  #取出填写的name的值
            if username == 'lily':
                return HttpResponse('*lily*')
        else:
            errors = form_obj.errors
            print("form is invalid T_T... ", errors)   # .errors 获取错误信息
            return render(request, 'form2/info.html', {'obj': form_obj, 'errors': form_obj.errors })
    return render(request, 'form2/info.html', {'obj': form_obj})

info.html

<form action="/form2/info" method="post">
    {% csrf_token %}
    {% for i in obj %}
    <div>{{ i.name }} {{ i }} {{ i.errors }} </div>   # i.name获取每个字段的名字,i.errors获取错误信息
    {% endfor %}
    <input type="submit" value="提交">
</form>

测试,输入一个非法的:

输入一个正确的:

ModelForm

因为models和form都能定义数据类型,如果想要数据库里的数据展示在前端,那么可以使用modelform,省去form定义字段类型。

例如:我已有了Article数据表。想要创建一个允许人们写文章的表单

myblog/models.py

# forms.py

from django import forms
from django.forms import ModelForm
from myblog import models    # 导入myblog.models数据表
class Article_Model_Form(forms.ModelForm):   #继承ModelForm类
    class Meta:            
        model = models.Article     #导入数据表
        fields = ['title', 'content']    #要使用的字段
exclude = () #排除字段

# views.py

from .forms import Article_Model_Form
def article_modelform(request):
    form = Article_Model_Form()  #创建一个表单来添加一条数据
    if request.method == 'POST':  
        form = Article_Model_Form(request.POST) 
        if form.is_valid():   # 判断表单是否合法
            print("form is ok", form.cleaned_data)
            form.save()   # 将合法的数据保存到数据表中
        else:
            error_msg = form.errors
            return render(request, 'form2/article.html', {"article_form": form ,"errors": error_msg})
    return render(request, 'form2/article.html', {"article_form": form})

# article.html

<form action="" method="post">
    {{ article_form }}
    <input type="submit" value="提交">
</form>

在表单填入 

可以从后台看到,数据创建成功。 

原文地址:https://www.cnblogs.com/hongdoudou/p/12572633.html