作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明。谢谢!
模板使用
之前是采用HttpResponse直接返回一些字符串,我们可以看到数据和视图是混合的
# return HttpResponse("<p> Hello ,world!</p>")
模板可以实现数据与视图分离
创建存放模板目录:
# mkdir templates/west -p
创建模板文件:
# vim templates/west/templay.html
# <h1>{{ label }}</h1>
标签已经标明在模板文件中
需要设置django搜索模板文件路径:mysite/setting.py
# 'DIRS': (os.path.join(BASE_DIR,'templates/west'),),
添加构建http响应方法,wests/view.py:
# def templay(request):
# context = {}
# context['label'] = 'hello,world!'
# return render(request, 'templay.html', context)
添加url匹配规则:
# url(r'^templay/','west.views.templay'),
测试:
# neo@neo-virtual-machine:~$ curl http://127.0.0.1:8000/west/templay/
# <h1>hello,world!</h1>
流程
模板将视图和数据分离开来
如果将数据库的数据放入到context中,就可以实现查看数据库的内容
# 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)
循环与选择
上面的方式,都是通过组合成字符串的方式,返回结果,staff实际上是一个数据容器(可迭代对象),我们也可以直接返回一个容器,在templay.html文件循环之后,显示
# def staff(request):
# staff_list = Character.objects.all()
# return render(request, 'templay.html',{'staffs': staff_list})
修改templay.html模板文件,循坏容器数据之后,在显示
# {% for item in staffs %}
# <p> {{ item.id }},{{ item }} </p>
# {% endfor %}
测试:
# neo@neo-virtual-machine:~$ curl http://127.0.0.1:8000/west/staff/
# <p> 1,ruiwen </p>
# <p> 2,namei </p>
# <p> 3,fatiao </p>
选择结构:
# {% if condition1 %}
# ... display 1
# {% elif condiiton2 %}
# ... display 2
# {% else %}
# ... display 3
# {% endif %}
elif 与 else 可以省略
模板与继承
模板可以采用继承的方式实现复用,测试采用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标签是可以被继承者替换掉的部分
在tmplay.html中继承base.html
html表格
web客户端发送请求,在请求中附加数据,服务器通过解析请求,获得客户端数据,根据URL来提供特定的服务。
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为索引。value表示按钮显示的值。
修改west/views.py文件:
# def form(request):
# return render(request,'form.html')
修改urls.py,对west/form的访问,指向form该视图
GET方法
表格中的数据是通过GET方法提交的,我们可以通过request.GET['staff'] ,来获得name为staff的输入栏数据,该数据是一个字符串,我们可以利用investigate()将直接显示该字符串。
设置west/views.py
# def investigate(request):
# rlt = request.GET['staff']
# return HttpResponse(rlt)
设置west/urls.py,设置对west/investigate的访问指定对应的视图
# url(r'^investigate/', 'west.views.investigate'),
访问west/form/就会显示输入栏和提交按钮,
当输入一些字符串之后,在提交,就会跳转到investigate,显示你输入的数据。
# http://127.0.0.1:8000/west/investigate/?staff=test
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()来处理表格:
# 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%}对应起来。
判断是否存在POST方法,匹配到staff将数据读取,在往页面显示数据。
存储数据
将客户端浏览器提交的数据存入数据库中,将字符串存入模型Character
修改west/views.py的investigate():
# 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 %}
测试:
点击submit显示数据库name字段内容,在输入栏输入数据之后,在点击submit,程序会将数据先存入到后台数据库,接着在读取数据库内容显示。
表格对象
客户提交数据后,服务器往往需要对数据做一些处理。比如检验数据,看是否符合预期的长度和数据类型。在必要的时候,还需要对数据进行转换,比如从字符串转换成整数。这些过程通常都相当的繁琐。
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 %}