官方文档tutorial 的第三章主要说的是 views.py url.py
在django中网页和内容通过views传递,每一个view由一个简单的python函数表示(或者方法)
写下第一个简单的view
在polls/views.py 里写下
from django.http import HttpResponse
def Index(request):
return HttpResponse("hello world ! This is my first django site")
然后在 poll/urls.py
from django.conf.urls import pattern, url
from polls import index
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
)
然后在根目录的urls.py里加上
url(r'^polls/', include('pols.urls')) 这里注意了 polls/后边没有美元符号,如果加了第一个测试没有问题,后边的测试polls/views里的内容全部不能显示
python manage.py runserver
测试可以看到我们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)
from django.conf.urls import patterns, url 修改 polls/views.py from polls import views urlpatterns = patterns('', # ex: /polls/ url(r'^$', views.index, name='index'), # ex: /polls/5/ url(r'^(?P<question_id>\d+)/$', views.detail, name='detail'), # ex: /polls/5/results/ url(r'^(?P<question_id>\d+)/results/$', views.results, name='results'), # ex: /polls/5/vote/ url(r'^(?P<question_id>\d+)/vote/$', views.vote, name='vote'), )
然后在根据我上边的注释测试
大体上看起来框架有了,但是有一个问题,我们数据库的内容一点没有显示
改动我们的index
不要忘了导入我们的polls.models
from polls.models import Question
def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] output = ', '.join([p.question_text for p in latest_question_list]) return HttpResponse(output)这次我们显示了最新的五个问题
仍然有一个问题,我们这里显示的页面都是硬编码进views.py 里边的,这样每次我们想要修改页面都要修改views
可以用模板系统把页面分理出去,
在polls 目录下创建templates django的会自动在app下的templates下寻找模板,而不用像第二节中所说的修改settings文件
关于组织模板:
我们可以把我们所有的模板放在一起,在一个大的templates目录下,它可以工作的非常好,然而,这个模板属于polls应用,所以不像我们创建的admin模板目录(上一节中)
我们将在后边的tutorial中深入讨论
在templates目录下在创建另一个polls, 并且在这个polls目录下创建一个叫做index.html的文件,换句话说你的模板应该在 polls/templates/polls/index.html
模板命名空间:
如果我们有多个应用,并且他们有相同的模板名的时候,django会选择她先找到的,所以我们需要命名空间来保证django找到我们需要的模板
index.html
{% 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 %} views.pyfrom django.shortcuts import render from polls.models import Question def index(request): latest_question_list = Question.objects.all().order_by('-pub_date')[:5] context = {'latest_question_list': latest_question_list} return render(request, 'polls/index.html', context)
然后解决detail view 问题的投票页面
polls.views 里边加上from django.http import Http404 from django.shortcuts import render from polls.models import Question # ... def detail(request, question_id): try: question = Question.objects.get(pk=question_id) except Question.DoesNotExist: raise Http404 return render(request, 'polls/detail.html', {'question': question})
如果找不到数据库中找不到这个问题的id 返回一个http404
解决上述问题的一个捷径from django.shortcuts import get_object_or_404, render from polls.models import Question # ... 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()函数需要两个参数,一个django的模型,另一个是一个任意的数字(数据可的keywords),将会传给数据库的get函数,如果对象没有出现,抛出404异常 运用模板系统 回到我们的detail()view 给出了 变量question, 这里是polls/detail.html<h1>{{ question.question_text }}</h1> <ul> {% for choice in question.choice_set.all %} <li>{{ choice.choice_text }}</li> {% endfor %} </ul>模板系统用 点号 来获得 变量的属性,详细参照我对关于template的那篇博客
是时候换掉 html中的硬编码了
index中的<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> 换为<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
templates的命名空间
根目录下的urls.py 改为urlpatterns = patterns('', url(r'^polls/', include('polls.urls', namespace="polls")), url(r'^admin/', include(admin.site.urls)), )
index 中的改为<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li><li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>