html的form表单
django中,前端如果要提交一些数据到views里面去,需要用到 html里面的form表单。
例如:
# form2/urls.py
from django.contrib import admin from django.urls import path,re_path from django.conf.urls import include from . import views urlpatterns = [ re_path(r'^home$', views.home), re_path(r'^login$', views.login), ]
# views.py
from django.shortcuts import render,HttpResponse def login(request): return render(request, 'form2/login.html')
# login.html
<form action="/form2/home" method="post"> #向这个页面发送post请求,action配置目标地址
<p>用户名:<input type="text" name="username"></p> #name表示key,value等于input输入的内容
<input type="submit" value="提交">
</form>
第二种方法: 使用url_name
login.html <form action="{% url 'homepage' %}" method="post">
urlpatterns = [
re_path(r'^home$', views.home,name='homepage'), #url命名
re_path(r'^login$', views.login),
]
<form action="{% url 'app_form2:homepage' %}" method="post">
path('form2/', include('form2.urls',namespace='aaaa')), #namespace必须有值,值好像可随便取~
app.urls
app_name = 'app_form2' #django2.0之后必须写此项,否则会报错
urlpatterns = [
re_path(r'^home$', views.home, name='homepage'), #url_name
# form2/views.py
from django.shortcuts import render,HttpResponse def login(request): return render(request, 'form2/login.html') def home(request): username = request.POST.get('username') or 'lily' #前端form表单传过来的username数据,如果为空则默认为'lily' 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数据表。想要创建一个允许人们写文章的表单
from django.db import models class Article(models.Model): title = models.CharField(max_length=32,default='Title') content = models.TextField(null=True) def __str__(self): return self.title
# 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>
在表单填入
可以从后台看到,数据创建成功。