视图是一个网页“类型”在django应用程序,提供特定的功能,并且具有特定的模板。例如,在一个博客的应用程序,可能有以下几个视图:
博客九游会下载首页 - 显示最后的几个文章。 进入“detail”页面- 对单个项目永久链接页面。 存档页 - 显示所有在给定年份各月的条目。 月存档页 - 显示所有给定月份各天的所有项。 天存档页 - 显示某一天所有条目。 评论操作 - 处理发布评论的一个给定输入。
在我们的 poll 应用程序,有以下四个视图:
问题的“index”页- 显示最后几个问题。 问题的“detail”页 - 显示一个问题文本,没有结果但有一个表单用来投票。 问题的“results”页面 - 显示结果一个特定问题。 投票操作 - 处理投票在一个特定的问题进行具体选择。
在django中,网页和其他内容由视图提供。每个视图由一个简单的python函数来表示(或方法,基于类的视图)。django会选择一个视图通过考察多数民众赞成请求的。
一个url模式是一个简单的url的一般形式 - 例如:/newsarchive/
现在,让我们添加一些视图在 polls/views.py。这些视图略有不同,因为他们需要一个参数:
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)
这些新的视图加入到 polls.urls 模块中如下的 调用,polls/urls.py文件中的代码如下:
from django.conf.urls import url from . import views urlpatterns = [ # ex: /polls/ url(/uploads/image/bdjango/r'^$',-nbsp;views.index,-nbsp;name='index'), # ex: /polls/5/ /$', views.detail, name='detail'), # ex: /polls/5/results/ /results/$', views.results, name='results'), # ex: /polls/5/vote/ /vote/$', views.vote, name='vote'), ]
您可以在浏览器打开“/polls/34/”。它会运行detail()方法,并显示任何提供的url内容。 再次尝试访问 “/polls/34/results/” and “/polls/34/vote/” – 这将显示占位符结果和投票页面。
include() 可以很容易包含入插件和网址。因为polls是在它们自己的url配置(polls/urls.py),它们可以放置在“/polls/”,或 “/fun_polls/”,或在“/content/polls/”,或任何其它路径的根,应用程序仍然可以工作。
下面是如果用户进入“/polls/34/”,在这个系统会发生什么:
django会找到匹配'^polls/' 然后,django会去掉匹配的文本("polls/")
并发送剩余的文本 – "34/" – 到'polls.urls'url配置用于进一步处理相匹配 r'^(?p
detail(request=, question_id='34')
question_id='34' 是来自 (?p
由于url模式是正则表达式,可以使用它来做一些事情,没有任何限制。而且也没有必要添加url为.html – 除非你想,在这种情况下,你可以这样做:
url(/uploads/image/bdrlatest/.html$',-nbsp;views.index),
每个视图负责做两件事情之一:返回包含所请求的页面内容的 httpresponse 对象,或抛出一个异常,如http 404。 修改polls/views.py文件代码如下:
from django.http import httpresponse from .models import question def index(request): latest_question_list = question.objects.order_by('-pub_date')[:5] output = ', '.join([q.question_text for q in latest_question_list]) return httpresponse(output) # leave the rest of the views (detail, results, vote) unchanged
在这里有一个问题就,通过:网页设计是硬编码在视图中。如果想改变页面的样子,必须编辑这个 python 代码。因此,让我们使用 django 模板系统通过创建视图可以使用模板来分开python 的代码。polls/templates/polls/index.html 将下面的代码:
{% if latest_question_list %}
no polls are available.
{% endif %}现在我们来更新九游会下载首页视图 polls/views.py使用以下模板(代码):
from django.http import httpresponse from django.template import loader from .models import question def index(request): latest_question_list = question.objects.order_by('-pub_date')[:5] template = loader.get_template('polls/index.html') context = { 'latest_question_list': latest_question_list, } return httpresponse(template.render(context, request))
该代码加载模板调用polls/index.html,然后传递给它的上下文。上下文是一个字典以python对象映射模板变量名。现在访问url(http://127.0.0.1:8000/polls/)查看结果 :
这是一个非常习惯用法来加载模板,填充上下文中和渲染模板的结果返回一个httpresponse对象。django提供了一个捷径。下面是完整的index() 视图,改写polls/views.py为:
from django.shortcuts import render from .models import question 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)
请注意,当在各个视图做到了这一点,我们不再需要导入加载器和httpresponse对象(想保留httpresponse,如果仍然有短截 detail, results, 和 vote 方法。
现在,让我们来解决这个问题详细视图 - 显示为给定的民意调查问题文本的页面。这里添加视图代码(polls/views.py):
from django.http import http404 from django.shortcuts import render from .models import question # ... def detail(request, question_id): try: question = question.objects.get(pk=question_id) except question.doesnotexist: raise http404("question does not exist") return render(request, 'polls/detail.html', {'question': question})
注意这里:视图引发http404异常,如果与请求id的问题并不存在。
我们将讨论可以把 polls/detail.html 在后面做一些修改,但如果想快速使用上面的实例,polls/templates/polls/detail.html 文件只需包含:
{{question}}
引发 404 错误,现在我们请求一个不存在问题,如:http://127.0.0.1:8000/polls/100/,显示结果如下:
如果对象不存在的一个非常习惯用法使用get()并引发http404错误。django提供了一个捷径。下面是 detail() 视图,polls/views.py 改写:
from django.shortcuts import get_object_or_404, render from .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模型作为第一个参数和关键字任意参数数量,它传递到模型管理的 get()函数。
如果对象不存在将引发http404。
还有一个get_list_or_404()函数,它的工作原理就像get_object_or_404()- 除了使用 filter()而不是get()方法。如果列表是空的它会引起http404。
回到我们的 polls 应用程序 detail() 视图。由于上下文变量的问题,这里的 polls/detail.html 模板看起来是这样的:
模板系统采用点查询语法来访问变量属性。在这个实例 {{question.question_text }},第一个django确实在question对象字典查找。 如果找不到,它再尝试属性查询 – 如果属性查找失败,它会尝试一个列表索引查找。
现在测试我们上面编写的代码,在浏览器中打开:http://127.0.0.1:8000/polls/5/ 得到结果如下:
请记住,当我们在 polls/index.html 链接到一个问题,链接被硬编码的部分是这样的:
使用此硬编码,紧密耦合的方法的问题是:它在更改项目的url用了很多模板。不过,既然 polls.urls模块中定义名称参数 函数,您可以通过使用 {% url %}模板删除标签在url配置中定义的特定url路径的依赖:
这种工作方式是通过为polls.urls模块中指定查找的url定义。可以准确地看到'detail'的url名称定义如下:
... # the 'name' value as called by the {% url %} template tag /$', views.detail, name='detail'), ...
如果你想要把投票详细视图的url更改成其它的,也许像 polls/specifics/12/ 取代在模板(或templates),需要在 polls/urls.py 改变它:
... # added the word 'specifics' /$', views.detail, name='detail'), ...
本教程项目只有一个应用程序 - polls。在实际的django项目中,可能有五个,十个,二十个或更多的应用程序。django 如何区分它们的url的名称? 例如,投票应用程序有一个详细视图,因此可能会在一个博客的同一个项目也有相同的应用程序。如何使用 {% url %} 模板标签让django知道创建一个url哪些应用有这样视图?
答案就是将命名空间添加到urlconf。在polls/urls.py文件,继续前进,添加应用程序名称设置应用程序命名空间,打开 polls/urls.py:
from django.conf.urls import url from . import views app_name = 'polls' urlpatterns = [ url(/uploads/image/bdjango/r'^$',-nbsp;views.index,-nbsp;name='index'), /$', views.detail, name='detail'), /results/$', views.results, name='results'), /vote/$', views.vote, name='vote'), ]
现在修改 polls/index.html 模板,打开 polls/templates/polls/index.html 文件添加以下代码:
使其指向在命名空间 detail 视图,打开 polls/templates/polls/index.html 文件如下: