7Python全栈之路系列之Django表单

Python全栈之路系列之Django表单

从Request对象中获取数据

HttpRequest对象包含当前请求URL的一些信息:


熟悉/方法 描述 例如
request.path 除域名以外的请求路径 /hello/
request.get_host() 访问的域名 127.0.0.1:8000” or www.example.com
request.get_full_path() 请求路径,可能包含查询字符串 /hello/?print=true
request.is_secure() 是否通过HTTPS访问 True或者False
request.get_host() 访问的主机端口 80/8080
request.META 返回一个字典,包含了所有的请求头信息 如果访问一个不存在的建会触发KeyError异常

一个返回所有request.META信息的页面函数:

def display_meta(request):
    values = request.META.items()
    html = []
    for k, v in values:
        html.append(‘<tr><td>%s</td><td>%s</td></tr>‘ % (k, v))
    return HttpResponse(‘<table>%s</table>‘ % ‘\n‘.join(html))

提交的数据信息

除了基本的元数据,HttpRequest对象还有两个属性包含了用户所提交的信息:request.GETrequest.POST,二者都是类字典对象,你可以通过它们来访问GET和POST数据。

我们说request.GET和request.POST是类字典对象,意思是他们的行为像Python里标准的字典对象,但在技术底层上他们不是标准字典对象。比如说,request.GET和request.POST都有get()、keys()和values()方法,你可以用用for key in request.GET获取所有的键。

一个简单的表单处理示例

通常,表单开发分为两个部分:前端HTML页面用户接口和后台view函数对所提交数据的处理过程,第一部分很简单;现在我们来建立个视图来显示一个用户搜索表单,这个页面的功能如下:

  1. 浏览器打开http://127.0.0.1:8000/search-form/,让用户输入一个用户名,然后搜索
  2. 如果用户搜索的用户名在数据库中存在,那么就返回这个用户的信息信息
  3. 如果用户不存在就返回和上面相同的页面,但是没有用户的信息信息
  4. 如果输入为空就提示用户输入为空

首先我们需要在darker这个app目录下面的views.py文件中加入以下内容:

from django.shortcuts import render_to_response
from darker.models import UserInfo

# Create your views here.

def search(request):
    # 定义一个变量error,默认为False
    error = False
    # 如果user在request.GET内
    if ‘user‘ in request.GET:
        # 获取request.GET[‘user‘]的值并赋值给username
        username = request.GET[‘user‘]
        # 如果username为空
        if len(username) == 0:
            # 那么就error = True
            error = True
        # 如果不为空
        else:
            # 在数据库中获取name=username的详细信息
            userinfo = UserInfo.objects.filter(name=username)
            # 跳转到页面search_results.html,传入两个值username和userinfo
            return render_to_response(‘search_results.html‘, {‘username‘: username, ‘userinfo‘: userinfo})
            
    # 如果user不存在在request.GET内或者如果username为空,就跳转到search_form.html页面并且传入一个值error
    return render_to_response(‘search_form.html‘, {‘error‘: error})

下面是一个搜索页面的html文件内容存在于templates/search_form.html内:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    # 如果传入过来的error=True
    {% if error %}
        # 那么就显示错误,否则就不显示
        <p style="color: red;">输入为空,请重新输入</p>
    {% endif %}
    
    <form action="" method="get">
        <input type="text" name="user">
        <input type="submit" value="搜索">
    </form>
</body>
</html>

然后在urls.py内添加视图,代码如下:

from django.conf.urls import url
from darker.views import search

urlpatterns = [
    url(r‘^search/‘, search),
]

templates下面的search_results.html文件内容如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>

<body>
<p>你搜索的用户名是: {{ username }}</p>

<p>用户信息如下</p>
{{ userinfo }}

</body>
</html>

打开浏览器,然后访问http://127.0.0.1:8000/search/,输入搜索的用户名,如果搜索到用户的信息就会返回错误信息

一个简单的验证

上述的实例中我们是否让用户填写一个用户名来判断用户是否存在亦或者填写的数据是否为空,那么现在我们再来做一个限制,就是如果用户输入为空,那么我们就提示输入为空,请重新输入,如果搜索的用户名大于10个字符那么就提示用户输入的用户名长度大于10,请重新输入

修改search函数为:

def search(request):
    errors = []
    if ‘user‘ in request.GET:
        username = request.GET[‘user‘]
        if len(username) == 0:
            errors.append("输入为空,请重新输入")
        elif len(username) > 10:
            errors.append("输入的用户名长度大于10,请重新输入")
        else:
            userinfo = UserInfo.objects.filter(name=username)
            return render_to_response(‘search_results.html‘, {‘username‘: username, ‘userinfo‘: userinfo})
    return render_to_response(‘search_form.html‘, {‘errors‘: errors})

修改search_form.html文件内容为:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    {% if errors %}
        <ul>
            {% for error in errors %}
            <li>{{ error }}</li>
            {% endfor %}
        </ul>
    {% endif %}
    
    <form action="" method="get">
        <input type="text" name="user">
        <input type="submit" value="搜索">
    </form>
</body>
</html>

最后就可以启动django然后重新访问http://127.0.0.1:8000/search/,在搜索框内输入空字段或者输入的字符大于10看看是什么结果。

Form类

Django带有一个form库,称为django.forms或者django.newforms,这个库可以处理HTML表单显示以及验证.

为什么有django.formsdjango.newforms

改名其实有历史原因的,当Django第一次向公众发行时,它有一个复杂难懂的表单系统:django.forms,后来它被完全重写了,新的版本改叫作:django.newforms,这样人们还可以通过名称,使用旧版本,当Django 1.0发布时,旧版本django.forms就不再使用了,而django.newforms也终于可以名正言顺的叫做:django.forms

darkerapp下创建forms.py文件,内容如下

from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField()
    email = forms.EmailField(required=False)
    message = forms.CharField()

上述代码中,表单中的每一个字段作为Form类的属性,被展现成Field类,这里只用到CharFieldEmailField类型,每一个字段都默认是必填,要使email成为可选项,我们需要指定required=False

Form对象做的第一件事是将自己显示成HTML

进入带django环境变量的解释器

E:\DarkerProjects>python manage.py shell
>>> from darker.forms import ContactForm
>>> f = ContactForm()
>>> f
<ContactForm bound=False, valid=Unknown, fields=(subject;email;message)>
>>> f.as_ul()
‘<li><label for="id_subject">Subject:</label> <input id="id_subject" name="subject" type="text" required /></li>\n<li><label for="id_email">Email:</label> <input id="id_email" name="email" type="email" /></li>\n<li><label for="id_message">Message:</label> <input id="id_message" name="message" type="text" required /></li>‘
>>> f.as_p()
‘<p><label for="id_subject">Subject:</label> <input id="id_subject" name="subject" type="text" required /></p>\n<p><label for="id_email">Email:</label> <input id="id_email" name="email" type="email" /></p>\n<p><label for="id_message">Message:</label> <input id="id_message" name="message" type="text" required /></p>

Form对象做的第二件事是校验数据

创建一个新的对Form象,并且传入一个与定义匹配的字典类型数据:

>>> f = ContactForm({‘subject‘: ‘Hello‘, ‘email‘: ‘[email protected]‘, ‘message‘: ‘Nice site!‘})
# 一旦你对一个Form实体赋值,你就得到了一个绑定form
>>> f.is_bound
True

is_valid()方法用来判断它的数据是否合法

# 如果数据合法则返回True
>>> f.is_valid()
True
# 否则返回False,这里只是指定了subject的值
>>> f = ContactForm({‘subject‘: ‘Hello‘})
>>> f.is_valid()
False

查看每个字段的出错消息

>>> f = ContactForm({‘subject‘: ‘Hello‘, ‘message‘: ‘‘})
>>> f[‘message‘].errors
[‘This field is required.‘]
>>> f[‘subject‘].errors
[]
>>> f[‘email‘].errors
[]

每个Form实体都有一个errors属性,它提供了一个字段与错误消息相映射的字典表

>>> f = ContactForm({‘subject‘: ‘Hello‘, ‘message‘: ‘‘})
>>> f.errors
{‘message‘: [‘This field is required.‘]}

更改改字段显示

当你在本地显示这个表单的时,message字段被显示成

<input id="id_message" name="message" type="text" required />

而它应该被显示成

<textarea cols="40" id="id_message" name="message" rows="10" required></textarea>

我们可以通过设置widget来修改它:

message = forms.CharField(widget=forms.Textarea)

设置主题最大长度

使subject限制在100个字符以内

subject = forms.CharField(max_length=100)

选项min_length参数设置最小长度

#Python全栈之路 #Django

时间: 2024-08-02 07:00:13

7Python全栈之路系列之Django表单的相关文章

1Python全栈之路系列之Django初体验

Python全栈之路系列之Django初体验 Django不得不说在Python中是一个非常强大的全栈框架,而且入门也比较简单,只要你学完了基本的Django知识,接着再做一两个项目,不大不小就成,然后你再去学其它的框架你会发现,在那些小而美的框架中,你学起来将非常的快,因为你在学习Django的时候就已经学习并且体验过了Web开发流程,所以会有这么一个现象出现,有些新手朋友在学习Flask.Tornado等小而美的框架时,很多概念不是很理解,比如ORM.路由等,但你学Django就不会出现这种

5Python全栈之路系列之Django模型续

Python全栈之路系列之Django模型续 连表操作一对一 在app的models.py文件内添加以下内容用户创建一对多关系的表: from django.db import models # Create your models here. class UserType(models.Model):     nid = models.AutoField(primary_key=True)     caption = models.CharField(max_length=32)      c

2Python全栈之路系列之Django路由与视图

Python全栈之路系列之Django路由与视图 路由说白了就是与视图(函数)的对应关系,怎么说呢,一个路由对应一个视图,比如上面文章中所提到的那样,当打开/users/路径的时候会让users这个函数来进行逻辑处理,把处理的结果再返回到前端. 那么django是怎么知道从哪里找路由的配置文件入口呢?其实这在settings.py文件中已经被定义了: ROOT_URLCONF = 'ansheng.urls' 路由的配置 绝对地址访问 # 访问地址必须是http://127.0.0.1:8000

4Python全栈之路系列之Django模型

Python全栈之路系列之Django模型 MTV开发模式 把数据存取逻辑.业务逻辑和表现逻辑组合在一起的概念有时被称为软件架构的Model-View-Controller(MVC)模式.在这个模式中,Model代表数据存取层,View代表的是系统中选择显示什么和怎么显示的部分,Controller指的是系统中根据用户输入并视需要访问模型,以决定使用哪个视图的那部分. Django紧紧地遵循这种MVC模式,可以称得上是一种MVC框架. 以下是Django中M.V和C各自的含义: **M**: 数

8Python全栈之路系列之Django Cookie 与Sessi

Python全栈之路系列之Django Cookie与Sessi Cookies cookies是浏览器为Web服务器存储的一小段信息,每次浏览器从某个服务器请求页面时,它向服务器回送之前收到的cookies. 存取Cookies 创建Cookies def set_cookie(request):     # 创建HttpResponse对象     Response = HttpResponse()     # 创建cookie     Response.set_cookie("Cookie

7Python全栈之路系列之协程

Python全栈之路系列之协程 What is the association? 与子例程一样,协程也是一种程序组件. 相对子例程而言,协程更为一般和灵活,但在实践中使用没有子例程那样广泛. 协程源自Simula和Modula-2语言,但也有其他语言支持. 协程更适合于用来实现彼此熟悉的程序组件,如合作式多任务,迭代器,无限列表和管道. 来自维基百科 https://zh.wikipedia.org/wiki/协程 协程拥有自己的寄存器上下文和栈,协程调度切换时,将寄存器上下文和栈保存到其他地方

7Python全栈之路系列之面向对象运算符重载

Python全栈之路系列之面向对象运算符重载 运算符重载的概念如下: 运算符重载让类拦截常规的Python运算: 类可重载所有Python表达式运算符: 类也可重载打印.函数调用.属性点号运算等内置运算: 重载是类实例的行为想内置类型: 重载是通过提供特殊名称的类方法来实现的: 常见的运算符重载方法 方法 重载 调用 __init__ 构造函数 对象建立:X = Class(args) __del__ 解析函数 X对象收回 __add__ 运算符+ 如果没有__iadd__,X+Y,X+=Y _

3Python全栈之路系列之MySQL表内操作

Python全栈之路系列之My SQL表内操作 先创创建一个表用于测试 -- 创建数据库 CREATE DATABASE dbname DEFAULT CHARSET utf8 COLLATE utf8_general_ci; -- 创建表 CREATE TABLE `tb` (   `id` int(5) NOT NULL AUTO_INCREMENT,   `name` char(15) NOT NULL,   `alias` varchar(10) DEFAULT NULL,   `ema

3Python全栈之路系列之D

Python全栈之路系列之Django模板 模板是一个文本,用于分离文档的表现形式和内容,模板定义了占位符以及各种用于规范文档该如何显示的各部分基本逻辑(模板标签).模板通常用于产生HTML,但是Django的模板也能产生任何基于文本格式的文档. 如何使用模板系统 在Python代码中使用Django模板的最基本方式如下: 可以用原始的模板代码字符串创建一个Template对象,Django同样支持用指定模板文件路径的方式来创建Template对象; 调用模板对象的render方法,并且传入一套