在Django中,网页和其他内容是通过视图传递的。每个视图由一个简单的Python函数表示,Django将通过检查请求的URL(准确地说,是域名后面的部分URL)来选择一个视图。
例如,用户在浏览器中访问 <<domain>>/newsarchive/<year>/<month>/
diango的URLConfs 将请求URL与对应的views function 匹配,调用view function 进行数据处理,然后选择对应的template模板进行渲染展示或直接数据返回。
在我们的poll app中,我们将会创建以下四个视图views:
- Question “index” page – displays the latest few questions.
- Question “detail” page – displays a question text, with no results but with a form to vote.
- Question “results” page – displays results for a particular question.
- Vote action – handles voting for a particular choice in a particular question.
编写views
polls/views.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
from django.http import HttpResponse #
Create your views here. def index(request): return HttpResponse( "Hello,
world. You're at the polls index." ) def detail(request,
question_id): return HttpResponse( "You're
looking at question %s." % question_id) def results(request,
question_id): response = "You're
looking at the results of question %s." return HttpResponse(response % question_id) def vote(request,
question_id): return HttpResponse( "You're
voting on question %s." % question_id) |
绑定URL与Views
polls/urls.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
from django.conf.urls import url from . import views urlpatterns = [ #
ex: /polls/ url(r '^$' ,
views.index, name = 'index' ), #
ex: /polls/5/ url(r '^(?P<question_id>[0-9]+)/$' ,
views.detail, name = 'detail' ), #
ex: /polls/5/results/ url(r '^(?P<question_id>[0-9]+)/results/$' ,
views.results, name = 'results' ), #
ex: /polls/5/vote/ url(r '^(?P<question_id>[0-9]+)/vote/$' ,
views.vote, name = 'vote' ), ] |
URLconfs 中,正则表达式中的分组()作为参数传递给view,如url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail')
假如请求url为 polls/34/ 相当于调用detail(request,question_id='34')
分别访问一下url可见调用不同的view 函数进行相应
http://localhost:8000/polls/
http://localhost:8000/polls/34/
http://localhost:8000/polls/34/results/
http://localhost:8000/polls/34/vote/
编写Views的数据库处理逻辑
view的主要工作:获取请求内容,调用数据库model获取数据库数据,调用业务处理Model逻辑处理,将处理结果渲染到指定的模板template中,响应response到客户端浏览器
创建 polls/templates,django会在在app目录下查找templates目录作为模板路径
创建 polls/templates/polls/index.html
Because of how the app_directories template loader works as described above, you can refer to this template within Django simply as polls/index.html.
(当然templates下不创建polls,模板路径调用index.html 也可以,但是强烈不建议这样,因为避免出现不同的app中有相同名称的模板文件时读取区分不出来)
1
2
3
4
5
6
7
8
9
|
{%
if latest_question_list %} < ul > {%
for question in latest_question_list %} < li >< a href="/polls/{{
question.id }}/">{{ question.question_text }}</ a ></ li > {%
endfor %} </ ul > {%
else %} < p >No
polls are available.</ p > {%
endif %} |
更新 index view in polls/views.py:
1
2
3
4
|
def index(request): latest_question_list = Question.objects.order_by( '-pub_date' )[: 5 ] context = { 'latest_question_list' :
latest_question_list} return render(request, 'polls/index.html' ,
context) |
访问 http://localhost:8000/polls/
编写Views 404异常
更新detail view in polls/views.py:
1
2
3
|
def detail(request,
question_id): question = get_object_or_404(Question,
pk = question_id) return render(request, 'polls/detail.html' ,
{ 'question' :
question}) |
get_object_or_404(),get_list_or_404() 当获取不到对象时,返回404页面
访问 http://localhost:8000/polls/34/
使用template模板
添加 polls/templates/polls/detail.html
1
2
3
4
5
6
|
< h1 >{{
question.question_text }}</ h1 > < ul > {%
for choice in question.choice_set.all %} < li >{{
choice.choice_text }}</ li > {%
endfor %} </ ul > |
django模板系统使用双大括号访问变量属性,如{{question.question_text}},
django模板中,使用 {% %}
将原生pyton语句包含起来,其中以上实例中,使用了for循环:{% for %} {% endfor %}
访问 http://localhost:8000/polls/1
修改template模板中的hardcoded URLs,统一使用{% url %} 标签替换
如polls/index.html 中的 <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
修改为:<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
这种URL 查找方式是通过polls.urls 中的name来匹配,如:
mysite/urls.py:
url(r'^polls/', include('polls.urls', namespace="polls")),
polls/urls.py:
# the 'name' value as called by the {% url %} template tag
url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
添加 URL namespace
如上例,使用{% url 'detail' %} 可以根据polls.urls 中的name='detail' 来匹配。如果在同一个project下有多个app,其中都有name='detail' 时,又该如何匹配views呢?
解决方法是,添加namespace到URLconf中,如在polls/urls.py 中添加: app_name = 'polls'
则可以在模板中修改{% url 'detail' %} 为 {% url 'polls:detail' %}
访问:http://localhost:8000/polls/
点击“what's up” 链接