Django(中)
来源:互联网 发布:sql删除一个字段的数据 编辑:程序博客网 时间:2024/05/21 10:31
一、模板初体验
我们拿一个独立的templay.html文件作为模板。它放在templates/west/文件夹下。文件系统的结构现在是:
mysite/├── mysite├── templates│ └── west└── west
templay.html文件的内容是:
<h1>{{ label }}</h1>
可以看到,这个文件中,有一个奇怪的双括号包起来的陌生人。这就是我们未来数据要出现的地方。而相关的格式控制,即<h1>标签,则已经标明在该模板文件中。
我们需要向Django说明模板文件的搜索路径,修改mysite/settings.py,添加:
# Template dirTEMPLATE_DIRS = ( os.path.join(BASE_DIR, 'templates/west/'),)
如果还有其它的路径用于存放模板,可以增加该元组中的元素,以便Django可以找到需要的模板。
我们现在修改west/views.py,增加一个新的对象,用于向模板提交数据:
# -*- coding: utf-8 -*-#from django.http import HttpResponsefrom django.shortcuts import renderdef templay(request): context = {} context['label'] = 'Hello World!' return render(request, 'templay.html', context)
可以看到,我们这里使用render来替代之前使用的HttpResponse。render还使用了一个词典context作为参数。这就是我们的数据。
context中元素的键值为'label',正对应刚才的“陌生人”的名字。这样,该context中的‘label’元素值,就会填上模板里的坑,构成一个完整的http回复。
作为上节内容的一个小练习,自行修改west/urls.py,让http://127.0.0.1:8000/west/templay的URL请求可以找到相应的view对象。
访问http://127.0.0.1:8000/west/templay,可以看到页面:
二、流程
再来回顾一下整个流程。west/views.py中的templay()在返回时,将环境数据context传递给模板templay.html。Django根据context元素中的键值,将相应数据放入到模板中的对应位置,生成最终的http回复。
这一模板系统可以与Django的其它功能相互合作。上一回,我们从数据库中提取出了数据。如果将数据库中的数据放入到context中,那么就可以将数据库中的数据传送到模板。
修改上次的west/views.py中的staff:
def staff(request): staff_list = Character.objects.all() staff_str = map(str, staff_list) context = {'label': ' '.join(staff_str)} return render(request, 'templay.html', context)
三、循环与选择
Django实际上提供了丰富的模板语言,可以在模板内部有限度的编程,从而更方便的编写视图和传送数据。
我们下面体验一下最常见的循环与选择。
上面的staff中的数据实际上是一个数据容器,有三个元素。刚才我们将三个元素连接成一个字符串传送。
实际上,利用模板语言,我们可以直接传送数据容器本身,再循环显示。修改staff()为:
def staff(request): staff_list = Character.objects.all() return render(request, 'templay.html', {'staffs': staff_list})
从数据库中查询到的三个对象都在staff_list中。我们直接将staff_list传送给模板。
将模板templay.html修改为:
{% for item in staffs %}<p>{{ item.id }}, {{item}}</p>{% endfor %}
我们以类似于Python中for循环的方式来定义模板中的for,以显示staffs中的每个元素。
还可以看到,对象.属性名的引用方式可以直接用于模板中。
选择结构也与Python类似。根据传送来的数据是否为True,Django选择是否显示。使用方式如下:
{% if condition1 %} ... display 1{% elif condiiton2 %} ... display 2{% else %} ... display 3{% endif %}
其中的elif和else和Python中一样,是可以省略的。
四、模板继承
模板可以用继承的方式来实现复用。我们下面用templay.html来继承base.html。这样,我们可以使用base.html的主体,只替换掉特定的部分。
新建templates/west/base.html:
<html> <head> <title>templay</title> </head> <body> <h1>come from base.html</h1> {% block mainbody %} <p>original</p> {% endblock %} </body></html>
该页面中,名为mainbody的block标签是可以被继承者们替换掉的部分。
我们在下面的templay.html中继承base.html,并替换特定block:
{% extends "base.html" %}{% block mainbody %}{% for item in staffs %}<p>{{ item.id }},{{ item.name }}</p>{% endfor %}{% endblock %}
第一句说明templay.html继承自base.html。可以看到,这里相同名字的block标签用以替换base.html的相应block。
五、html表格
HTTP协议以“请求-回复”的方式工作。客户发送请求时,可以在请求中附加数据。服务器通过解析请求,就可以获得客户传来的数据,并根据URL来提供特定的服务。
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 renderdef form(request): return render(request, 'form.html')
设置urls.py,让对[site]/west/form/的访问,指向该视图。
最后,我们在west/views.py中定义investigate()来处理该表格提交的数据:
from django.shortcuts import renderdef 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 renderfrom django.core.context_processors import csrfdef 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 renderfrom django.core.context_processors import csrffrom west.models import Characterdef 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 renderfrom django.core.context_processors import csrffrom west.models import Characterfrom django import formsclass 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>标签。
效果如下:
- Django(中)
- 【Django】settings(django中settings设置)
- 【Django】settings(django中settings设置)
- django基础入门(2)django中第一…
- Django中生成PDF(一)
- Django中使用tiny_mce
- django中使用tagging
- Django中使用CKEditor
- DJANGO中操作数据库
- django中url配置
- django中搜索表单
- django中json处理
- django中获取sessionid
- django中字段类型
- Django中template 使用
- python中django安装
- django 中发送邮件
- Django 中 urls 使用
- 在Linux下安装windows后解决Linux不能启动能问题
- 黑苹果系统迁移
- 关于抽象类的几个简单理解
- 杭州电子科技大学acm---2008
- 九度oj 1055
- Django(中)
- loadrunner中sprintf函数的用法
- ubuntu卸载安装包
- 树结构的自定义及基本算法(Java数据结构学习笔记)
- 20150816 开始捡起以前地专业!
- JAVA反射机制获取类和方法
- codefroces 并查集 250 D
- HDU 1536(sg博弈) S-Nim
- HDOJ 题目分类