前面的内容我们基本上以 get
请求作为例子,那 post
请求Django是如何处理的呢?本章内容我们就来介绍Django如何发起和处理 post
请求的。
就拿我们的Cat类来说,之前新增Cat对象都是通过admin后台或者数据库API来操作,现在我们尝试通过前端页面来添加Cat对象。
首先我们新建一个简单的新增Cat对象的模板,新建 'demo_app/add.html'
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/html"><head> <meta charset="UTF-8"> <title>add cat</title></head><body> <form action="{% url 'demo_app:add' %}" method="post"> {% csrf_token %}
name:<input name="name"> </br> age :<input name="age" ></br>
<input type="submit" value="submit"> </form>
</body></html>
method="post"
,并且我们将action 设置为 {%url'demo_app:add'%}
, 这表明了了我们会像 demo_app/views
中的 add方法发送数据。{%csrf_token%}
是Django 用来防止跨站点请求伪造。Django 内部的POST表单都要如此。我们还要创建一个视图来实现这个新增cat 的功能。将下面的代码添加到 deom_app/views.py
文件中
def add(request): if request.method == 'GET': return render(request, 'demo_app/add.html',{}) if request.method == 'POST': name = request.POST['name'] age = int(request.POST['age']) cat = Cat(name=name, age=age) cat.save() cats_list = Cat.objects.all() return render(request,'demo_app/index.html',{'cats_list':cats_list})
request.method
表示该请求的方法类型,是 GET 还是 POST,或者其他 如 PUT ,DELETE等类型。
ifrequest.method=='GET':returnrender(request,'demo_app/add.html',{})
表示如果是GET请求时,则系统跳转到 add 页面(比较简陋)
request.POST
是一个类字典对象,让你可以通过关键字的名字获取提交的数据,需要注意的是,返回的值永远是字符串。request.method=='POST'
时 (表示 如果是 POST 请求时),则取出请求中的name 和 age 关键字的 数据, 新增对象,并直接返回index页面(list页面)修改 demo_proj/urls.py
文件
from django.contrib import adminfrom django.conf.urls import includefrom django.urls import path
urlpatterns = [ path('admin/', admin.site.urls), path('demo_app/', include(('demo_app.urls','demo_app'), namespace='demo_app'))]
修改 demo_app/urls.py
文件
urlpatterns = [ path('', views.index, name='index'), path('hello/<str:country_name>/', views.hello_country, name='hello'), path('add/', views.add, name='add'),]
action
为 {%url'demo_app:add'%}
,所以要注意include 中的写法,如果 include
方法中 namespace
为其他值,如 demo_app1
,那么 action
中因为 {%url'demo_app1:add'%}
经过上面的配置,我们就能演示从前端新增cat 对象功能了。我们首先跳转到add 页面
点击提交,页面跳转至 list 页面
功能是实现了,但比较简陋,还不完善。就比如,字段是否必填,字段的长度是否超出最大范围,为避免这样的错误,我们必须对字段进行校验,那么我们就在views.py 文件中加上 校验的业务逻辑代码,如下所示:
def add(request): if request.method == 'GET': return render(request, 'demo_app/add.html',{}) elif request.method == 'POST': name = request.POST['name'] age = int(request.POST['age'])
# 新增字段校验逻辑 if name ...: pass
else: pass
cat = Cat(name=name, age=age) cat.save() cats_list = Cat.objects.all() return render(request,'demo_app/index.html',{'cats_list':cats_list})
这样固然能达到效果,但如果字段很多的话,代码将非常臃肿,弊端很大。Django 为此提出了一种较为简便的方法Form ,Django 中的表单有一下两个作用:
下面我们来介绍下他的使用。
forms.py
文件
在 demo_app
目录下新建 froms.py
文件from django.forms import forms
class AddFrom(forms.Form): name = forms.CharField(required=True, max_length=10, label='name_form') age = forms.IntegerField(required=True)
name=forms.CharField(required=True,max_length=10,label='name_form')
定义了 name
这个字段是字符串类型的,且是必填的,最大长度为10, label='name_form'
的作用是渲染html 表单中字段为 name
的 label
为 name_form
。age=forms.IntegerField(required=True)
定义了 age
为个整数类型的字段,且是必填的。views.py
文件
修改 demo_app/views.py文件
(为区分根之前版本的不同,我将之前版本的注释掉,以便比较)def add(request): if request.method == 'GET': # return render(request, 'demo_app/add.html',{}) form = AddFrom() return render(request, 'demo_app/add.html',{'form':form}) elif request.method == 'POST': # name = request.POST['name'] # age = int(request.POST['age']) # cat = Cat(name=name, age=age) # cat.save() # cats_list = Cat.objects.all() # return render(request, 'demo_app/index.html', {'cats_list': cats_list}) form = AddFrom(request.POST) if form.is_valid(): name = request.POST['name'] age = int(request.POST['age']) cat = Cat(name=name, age=age) cat.save() cats_list = Cat.objects.all() return render(request,'demo_app/index.html',{'cats_list':cats_list})
AddFrom
实例,并将它作为上下文传递给前端,这样就达到了渲染表单的效果。AddFrom
实例 并用请求数据填充它 form=AddFrom(request.POST)
,我们称作为 数据绑定表单。form.is_valid()
表示对POST请求中的数据按照当时定义表单字段时定义的规则校验。如 age=forms.IntegerField(required=True)
就会对 请求中的 nage 为 age 的字段进行校验,判断它是否为必填(是否传了),只有所有字段都通过校验后才能进行下面的逻辑。is_valid()
不通过的情况,代码可以大家继续完善。templates/dem_app/add.html
文件,(为区分根之前版本的不同,我将之前版本的注释掉,以便比较)<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/html"><head> <meta charset="UTF-8"> <title>add cat</title></head><body> <form action="{% url 'demo_app:add' %}" method="post"> {% csrf_token %} {{ form }} {# name:<input name="name"> </br>#} {# age : <input name="age" ></br>#}
<input type="submit" value="submit"> </form>
</body></html>
<form>
标签中,只有 {{form}}
了,这就是 渲染表单模板 的作用我们运行程序可以到同样的效果,大家也可以试试当输入的 name
或 age
不符合条件的情况系统会是什么反应。
我们一般推荐不用表单渲染,因为样式不受自己控制,另外当我们 is_valid()
返回true 后,我们可以通过 cleaned_data
属性中找到所有通过验证的表单数据,这个大家可以自己探索下。