被解放的姜戈04 各取所需

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢! 

 

我们在庄园疑云中讲到了服务器上的数据。当时我们是用手动的方式,直接在数据库插入数据。我们将允许客户向服务器传递数据。

表格是客户向服务器传数据的经典方式。我们先会看到传统的表格提交,然后了解Django的表格对象。

 

“我可不做赔本的买卖”,庄主对姜戈说。

 

html表格

HTTP协议以“请求-回复”的方式工作。客户发送请求时,可以在请求中附加数据。服务器通过解析请求,就可以获得客户传来的数据,并根据URL来提供特定的服务。 

(http协议的运作方式,详见http协议

 

HTML文件中可以包含表格标签。HTML表格的目的是帮助用户构成HTTP请求,把数据用GET或者POST的方法,传递给某一URL地址。下面是一个表格的例子:

<form action="/west/investigate/" method="get">
  <input type="text" name="staff">
  <input type="submit" value="Submit">
</form>

这里的form标签有两个属性。action用于说明URL地址,method说明请求的方法。

表格中还包含有两个input标签,即两个输入栏目。根据type的不同,第一个为一个文本框,第二个为一个提交按钮。name为输入栏的名字。服务器在解析数据时,将以name为索引。

 

我们可以将上面的表格直接存入模板form.html,并在west/views.py中定义一个视图form()来显示表格:

from django.shortcuts import render

def form(request):
    return render(request, 'form.html')

设置urls.py,让对[site]/west/form/的访问,指向该视图。

 

最后,我们在west/views.py中定义investigate()来处理该表格提交的数据:

from django.shortcuts import render

def investigate(request):
    rlt = request.GET['staff']
    return HttpResponse(rlt)

可以看到,HTTP请求的相关信息,包括请求的方法,提交的数据,都包含在request参数中。

表格是通过GET方法提交的。我们可以通过request.GET['staff'],来获得name为staff的输入栏的数据。该数据是一个字符串。investigate()将直接显示该字符串。

设置urls.py,让该处理函数对应action的URL([site]/west/investigate/)。

 

当我们访问http://127.0.0.1:8000/west/form时,将显示:

提交表格后,页面将转到[site]/west/investigate。investigate()读取字符串后,在页面上显示出来。

 

姜戈舔舔嘴唇,“这就是你最好的决斗士?我觉得它们不值。”

 

POST方法

上面我们使用了GET方法。视图显示和请求处理分成两个函数处理。

提交数据时更常用POST方法。我们下面使用该方法,并用一个URL和处理函数,同时显示视图和处理请求。

 

先创建模板investigate.html

<form action="/west/investigate/" method="post">
  {% csrf_token %}
  <input type="text" name="staff">
  <input type="submit" value="Submit">
</form>

<p>{{ rlt }}</p>

我们修改提交表格的方法为post。在模板的末尾,我们增加一个rlt记号,为表格处理结果预留位置。

表格后面还有一个{% csrf_token %}的标签。csrf全称是Cross Site Request Forgery。这是Django提供的防止伪装提交请求的功能。POST方法提交的表格,必须有此标签。

 

在west/views.py中,用investigate()来处理表格:

from django.shortcuts import render
from django.core.context_processors import csrf

def investigate(request):
    ctx ={}
    ctx.update(csrf(request))
    if request.POST:
        ctx['rlt'] = request.POST['staff']
    return render(request, "investigate.html", ctx)

这里的csrf()是和上面的{% csrf_token %}对应。我们在这里不深究。

看程序的其它部分。对于该URL,可能有GET或者POST方法。if的语句有POST方法时,额外的处理,即提取表格中的数据到环境变量。

 

最终效果如下:

“哦,是吗,我可是有更好的货色”,庄主似乎胸有成竹。 

 

存储数据

我们还可以让客户提交的数据存入数据库。使用庄园疑云中创建的模型。我们将客户提交的字符串存入模型Character。

 

修改west/views.py的investigate():

from django.shortcuts import render
from django.core.context_processors import csrf

from west.models import Character

def investigate(request):
    if request.POST:
        submitted  = request.POST['staff']
        new_record = Character(name = submitted)
        new_record.save()
    ctx ={}
    ctx.update(csrf(request))
    all_records = Character.objects.all()
    ctx['staff'] = all_records
    return render(request, "investigate.html", ctx)

在POST的处理部分,我们调用Character类创建新的对象,并让该对象的属性name等于用户提交的字符串。通过save()方法,我们让该记录入库。

随后,我们从数据库中读出所有的对象,并传递给模板。

 

我们还需要修改模板investigate.html,以更好的显示:

<form action="/west/investigate/" method="post">
  {% csrf_token %}
  <input type="text" name="staff">
  <input type="submit" value="Submit">
</form>

{% for person in staff %}
<p>{{ person }}</p>
{% endfor %}

我们使用模板语言的for,来显示所有的记录。

 

效果如下:

“他只是勉强够看罢了”,姜戈摇摇头,德国人也赶快跟着摇摇头。 

 

表格对象

客户提交数据后,服务器往往需要对数据做一些处理。比如检验数据,看是否符合预期的长度和数据类型。在必要的时候,还需要对数据进行转换,比如从字符串转换成整数。这些过程通常都相当的繁琐。

Django提供的数据对象可以大大简化这一过程。该对象用于说明表格所预期的数据类型和其它的一些要求。这样Django在获得数据后,可以自动根据该表格对象的要求,对数据进行处理。

 

修改west/views.py:

from django.shortcuts import render
from django.core.context_processors import csrf

from west.models import Character

from django import forms

class CharacterForm(forms.Form):
    name = forms.CharField(max_length = 200)

def investigate(request):
    if request.POST:
        form = CharacterForm(request.POST)
        if form.is_valid():
            submitted  = form.cleaned_data['name']
            new_record = Character(name = submitted)
            new_record.save()

    form = CharacterForm()
    ctx ={}
    ctx.update(csrf(request))
    all_records = Character.objects.all()
    ctx['staff'] = all_records
    ctx['form']  = form
    return render(request, "investigate.html", ctx)

上面定义了CharacterForm类,并通过属性name,说明了输入栏name的类型为字符串,最大长度为200。

在investigate()函数中,我们根据POST,直接创立form对象。该对象可以直接判断输入是否有效,并对输入进行预处理。空白输入被视为无效。

后面,我们再次创建一个空的form对象,并将它交给模板显示。

 

在模板investigate.html中,我们可以直接显示form对象:

<form action="/west/investigate/" method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <input type="submit" value="Submit">
</form>

{% for person in staff %}
<p>{{ person }}</p>
{% endfor %}

如果有多个输入栏,我们可以用相同的方式直接显示整个form,而不是加入许多个<input>标签。

 

效果如下:

 

庄主看看德国人,再看看女仆,脸上露出狡猾的笑容。

 

总结

GET和POST

表格提交

数据库入库

表格对象

 

“哈,那个德国人似乎看上了这个黑女仆呢”,庄主心里打着算盘。

 

欢迎阅读“被解放的姜戈”系列文章。

 

 

时间: 2024-10-26 02:27:59

被解放的姜戈04 各取所需的相关文章

被解放的姜戈08 远走高飞

作者:Vamei 出处:http://www.cnblogs.com/vamei 转载请先与我联系.    之前在单机上实现了一个Django服务器(被解放的姜戈07 马不停蹄),现在我们可以把这个服务器推上一个云平台.这里我选择使用阿里云.   看着复仇的火焰燃烧,姜戈露出得意的笑容.   阿里云准备 在阿里云官网(aliyun.com)页面注册阿里云账号.登录后选择云服务器ECS,并选择"创建实例": 选择操作系统Ubuntu 14.04 64位,设置密码.实例开通后,可以在实例记

被解放的姜戈01 初试天涯

原文:被解放的姜戈01 初试天涯  作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢!   Django是Python下的一款网络服务器框架.Python下有许多款不同的框架.Django是重量级选手中最有代表性的一位.许多成功的网站和APP都基于Django.虽然Django之于Python,达不到Rail之于Ruby的一统江湖的地位,但Django无疑也是Python在网络应用方面的一位主将.   向昆汀的致敬,"被解放的姜戈

被解放的姜戈02 庄园疑云

原文:被解放的姜戈02 庄园疑云 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢!   上一回说到,姜戈的江湖初体验:如何架设服务器,如何回复http请求,如何创建App.这一回,我们要走入糖果庄园.   数据库是一所大庄园,藏着各种宝贝.一个没有数据库的网站,所能提供的功能会非常有限.   为了找到心爱的人,姜戈决定一探这神秘的糖果庄园.   连接数据库 Django为多种数据库后台提供了统一的调用API.根据需求不同,Dja

被解放的姜戈07 马不停蹄

原文:被解放的姜戈07 马不停蹄 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢!    前面的文章研究了Django最主要的几个方面:数据库,模板,动态生成页面等.但都是使用python manage.py runserver来运行服务器.这是一个实验性的web服务器,不适用于正常的站点运行.我们需要一个可以稳定而持续的服务器.这个服务器负责监听http端口,将收到的请求交给Django处理,将Django的回复发还给客户端.

被解放的姜戈05 黑面管家

原文:被解放的姜戈05 黑面管家 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢!    Django提供一个管理数据库的app,即django.contrib.admin.这是Django最方便的功能之一.通过该app,我们可以直接经由web页面,来管理我们的数据库.这一工具,主要是为网站管理人员使用. 这个app通常已经预装好,你可以在mysite/settings.py中的INSTALLED_APPS看到它. "这庄园里的

被解放的姜戈03 所谓伊人

原文:被解放的姜戈03 所谓伊人 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢!   在之前的程序中,我们直接生成一个字符串,作为http回复,返回给客户端.这一过程中使用了django.http.HttpResponse(). 在这样的一种回复生成过程中,我们实际上将数据和视图的格式混合了到上面的字符串中.看似方便,却为我们的管理带来困难.想像一个成熟的网站,其显示格式会有许多重复的地方.如果可以把数据和视图格式分离,就可以

被解放的姜戈06 假作真时

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢!   之前了解了: 创建Django项目 数据库 模板 表格提交 admin管理页面 上面的功能模块允许我们做出一个具有互动性的站点,但无法验证用户的身份.我们这次了解用户验证部分.通过用户验证,我们可以根据用户的身份,提供不同的服务.   一个Web应用的用户验证是它的基本组成部分.我们在使用一个应用时,总是从"登录"开始,到"登出"结束.另一方面,

Python快速教程

原文:Python快速教程 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢!   怎么能快速地掌握Python?这是和朋友闲聊时谈起的问题. Python包含的内容很多,加上各种标准库,拓展库,乱花渐欲迷人眼.一直希望写一个快速的.容易上手的Python教程.目标是做到言语简洁,循序渐进,让没有背景的读者也可以从基础开始学习.我在每一篇中专注于一个小的概念,希望在闲暇时可以很快读完. 小提醒 教程将专注于Python基础,语法基

都是逆袭,都是秒杀,这差别咋这么大呢?

<箭在弦上>中,抗日女兵徐二航被日本兵强奸后突然暴走,秒杀敌人. <被解放的姜戈>中,黑奴姜戈从被奴隶主虐待到逆袭的过程充满各种血腥戏码. 逆袭!秒杀!这个春天的影视剧都开挂了?近日,一部名为<箭在弦上>的抗日剧,以"抗日女兵遭轮奸后突然小宇宙爆发秒杀众鬼子"的"神剧情"走红网络,无论剧情.表演.台词无一不被纷纷吐槽是"神逻辑"."无厘头".抗日剧种种逆天到近似科幻的桥段,近来屡屡受到网友和