视图view
接上一篇
官方对视图的解释:在 Django 中,网页和其他内容都是从视图派生而来。每一个视图表现为一个简单的 Python 函数(或者说方法,如果是在基于类的视图里的话)。Django 将会根据用户请求的 URL 来选择使用哪个视图(更准确的说,是根据 URL 中域名之后的部分)。
就是说Django中应用中的视图放在应用目录下的views.py文件中作为一个待返回结果的函数,我们利用url_conf来调用对应url下的视图
1.创建运用视图
这用到了detail.html模板 我们要在polls/temlates/polls/下创建detail.html文件
内容暂为:
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
向polls/views.py中添加视图(函数)
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
from .models import Question
#应用主页面,这里把最新的5个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)
#某投票细节页面,简单展示是否存在,若是则返回投票文本,若否则返回404
# Leave the rest of the views (detail, results, vote) unchanged
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
#展示结果页面,,,
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模块中添加url函数调用
这里path函数中的尖括号:使用尖括号“捕获”这部分 URL,且以关键字参数的形式发送给视图函数。上述字符串的 :question_id> 部分定义了将被用于区分匹配模式的变量名,而< int: 则是一个转换器决定了应该以什么变量类型匹配这部分的 URL 路径。继而url中该位置的变量传入对应的视图函数。
from django.urls import path
from . import views
urlpatterns = [
# ex: /polls/
path('', views.index, name='index'),
# ex: /polls/5/
path('<int:question_id>/', views.detail, name='detail'),
# ex: /polls/5/results/
path('<int:question_id>/results/', views.results, name='results'),
# ex: /polls/5/vote/
path('<int:question_id>/vote/', views.vote, name='vote'),
]
示例:
访问127.0.0.1/polls/1,127.0.0.1/polls/2,127.0.0.1/polls/3
2.创建运用模板
创建:
polls 目录里创建一个 templates 目录。Django 将会在这个目录里查找模板文件。项目的 TEMPLATES 配置项描述了 Django 如何载入和渲染模板。默认的设置文件设置了 DjangoTemplates 后端,并将 APP_DIRS 设置成了 True。这一选项将会让 DjangoTemplates 在每个 INSTALLED_APPS 文件夹中寻找 “templates” 子目录。
在创建的 templates 目录里,再创建一个目录 polls。
这样做的原因:
官方文档:虽然我们现在可以将模板文件直接放在 polls/templates 文件夹中(而不是再建立一个 polls 子文件夹),但是这样做不太好。Django 将会选择第一个匹配的模板文件,如果你有一个模板文件正好和另一个应用中的某个模板文件重名,Django 没有办法 区分 它们。我们需要帮助 Django 选择正确的模板,最简单的方法就是把他们放入各自的 命名空间 中,也就是把这些模板放入一个和 自身 应用重名的子文件夹里。
运用:
模板系统统一使用点符号来访问变量的属性。
在detail.html该模板中,模板对views.detail()视图传递来的变量question进行了运用
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
3.去除URL硬编码和维对URL名称添加命名空间
在polls/index.html中的链接
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
在硬编码和强耦合的链接,对于一个包含很多应用的项目来说,修改起来是十分困难的。然而,因为在 polls.urls 的 url() 函数中通过 name 参数为 URL 定义了名字,可以使用 {% url %} 标签代替它:
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
这样子当想改变detail的URL时就只用在urls.py中修改该path就ok了
命名空间的必要
官方文档:
在一个真实的 Django 项目中,可能会有五个,十个,二十个,甚至更多应用。Django 如何分辨重名的 URL 呢?举个例子,polls 应用有 detail 视图,可能另一个博客应用也有同名的视图。Django 如何知道 {% url %} 标签到底对应哪一个应用的 URL 呢?
答案是:在根 URLconf 中添加命名空间。在 polls/urls.py 文件中稍作修改,加上 app_name 设置命名空间:
未使用命名空间:
<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>