前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Django -- 如何优雅的提交表单

Django -- 如何优雅的提交表单

作者头像
周辰晨
发布2020-01-19 19:12:08
3.2K0
发布2020-01-19 19:12:08
举报

前言

前面的内容我们基本上以 get请求作为例子,那 post请求Django是如何处理的呢?本章内容我们就来介绍Django如何发起和处理 post请求的。


一个简单的表单

就拿我们的Cat类来说,之前新增Cat对象都是通过admin后台或者数据库API来操作,现在我们尝试通过前端页面来添加Cat对象。

模板

首先我们新建一个简单的新增Cat对象的模板,新建 'demo_app/add.html'

代码语言:javascript
复制
<!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>
  • 在html文件中,我们定义了一个Form 表单,提交的这个表单会改变服务端的数据,所以我们将 method="post" ,并且我们将action 设置为 {%url'demo_app:add'%}, 这表明了了我们会像 demo_app/views中的 add方法发送数据。
  • {%csrf_token%} 是Django 用来防止跨站点请求伪造。Django 内部的POST表单都要如此。
视图

我们还要创建一个视图来实现这个新增cat 的功能。将下面的代码添加到 deom_app/views.py 文件中

代码语言:javascript
复制
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页面)
URL配置

修改 demo_proj/urls.py 文件

代码语言:javascript
复制
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 文件

代码语言:javascript
复制
urlpatterns = [    path('', views.index, name='index'),    path('hello/<str:country_name>/', views.hello_country, name='hello'),    path('add/', views.add, name='add'),]
  • 因为我们指定了Form表单的 action{%url'demo_app:add'%},所以要注意include 中的写法,如果 include 方法中 namespace 为其他值,如 demo_app1,那么 action中因为 {%url'demo_app1:add'%}

经过上面的配置,我们就能演示从前端新增cat 对象功能了。我们首先跳转到add 页面

点击提交,页面跳转至 list 页面


Form进阶

功能是实现了,但比较简陋,还不完善。就比如,字段是否必填,字段的长度是否超出最大范围,为避免这样的错误,我们必须对字段进行校验,那么我们就在views.py 文件中加上 校验的业务逻辑代码,如下所示:

代码语言:javascript
复制
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 中的表单有一下两个作用:

  • 渲染表单模板
  • 验证数据是否合法

下面我们来介绍下他的使用。

  1. 在相应的App下新建 forms.py文件 在 demo_app 目录下新建 froms.py 文件
代码语言:javascript
复制
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 表单中字段为 namelabelname_form
  • age=forms.IntegerField(required=True) 定义了 age 为个整数类型的字段,且是必填的。
  1. 修改 views.py文件 修改 demo_app/views.py文件(为区分根之前版本的不同,我将之前版本的注释掉,以便比较)
代码语言:javascript
复制
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})
  • 当请求是 GET 请求时,新建了一个 AddFrom 实例,并将它作为上下文传递给前端,这样就达到了渲染表单的效果。
  • 当请求是 POST请求时,我们再次创建了一个 AddFrom 实例 并用请求数据填充它 form=AddFrom(request.POST) ,我们称作为 数据绑定表单。
  • form.is_valid() 表示对POST请求中的数据按照当时定义表单字段时定义的规则校验。如 age=forms.IntegerField(required=True) 就会对 请求中的 nage 为 age 的字段进行校验,判断它是否为必填(是否传了),只有所有字段都通过校验后才能进行下面的逻辑。
  • 这边代码只是 演示作用,没有写 is_valid()不通过的情况,代码可以大家继续完善。
  1. 修改模板文件 修改 templates/dem_app/add.html文件,(为区分根之前版本的不同,我将之前版本的注释掉,以便比较)
代码语言:javascript
复制
<!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}}了,这就是 渲染表单模板 的作用

我们运行程序可以到同样的效果,大家也可以试试当输入的 nameage不符合条件的情况系统会是什么反应。

我们一般推荐不用表单渲染,因为样式不受自己控制,另外当我们 is_valid()返回true 后,我们可以通过 cleaned_data属性中找到所有通过验证的表单数据,这个大家可以自己探索下。

前文回顾
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-12-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 架构师影响力 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一个简单的表单
    • 模板
      • 视图
        • URL配置
        • Form进阶
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档