View
目前目录结构:
基本思想:view在views.py中被定义为一个方法,通过正则表达式调用相应的view
urls.py(定义正则) --> views.py (定义view)
- mysite/urls.py:
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
#将所有polls开头的请求映射到引入的polls.urls上,注意include的用法
url(r'^polls/', include('polls.urls')),
]
url()
函数具有四个参数:两个必需的regex和 view,以及两个可选的kwargs和name。
- view参数:如果正则表达式使用简单的捕获方式,值将作为位置参数传递; 如果使用命名的捕获方式,值将作为关键字参数传递。
- kwargs参数:任何关键字参数都可以以字典形式传递给目标视图
- name参数:命名你的URL。 这样就可以在Django的其它地方尤其是模板中,通过名称来明确地引用这个URL。 这个强大的特性可以使你仅仅修改一个文件就可以改变全局的URL模式。
- polls/urls.py:
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'),
]
上面正则的说明:正则表达式30分钟教程 及正则基础之——捕获组(capture group)
?P<question_id> 是捕获组设定
- polls/views.py:
from django.shortcuts import render, get_object_or_404
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)
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)
注意引入的render和get_object_or_404的用法
- polls/templates/polls/index.html
我们可以直接将我们的模板放在polls/templates中(而不用创建另外一个polls子目录),但实际上这是个坏主意。Django将选择它找到的名字匹配的第一个模板文件,如果你在不同 的应用有相同名字的模板文件,Django将不能区分它们。我们需要将Django指向正确的模板,最简单的方式是使用命名空间。具体实现方式是,将这些模板文件放在以应用的名字来命名的另一个目录下。
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<!--注意此处url为硬编码方式,需要修改-->
<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
这种硬编码、紧耦合的方法有一个问题,就是如果我们想在拥有许多模板文件的项目中修改URLs,那将会变得很有挑战性。 然而,因为你在polls.urls模块的url()函数中定义了name 参数,你可以通过使用{% url %}模板标签来移除对你的URL配置中定义的特定的URL的依赖:
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
如果你想把polls应用中detail视图的URL改成其它样子比如 polls/specifics/12/,就可以不必在该模板(或者多个模板)中修改它,只需要修改 polls/urls.py:
url(r'^specifics/(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
- 在真实的Django项目中,可能会有五个、十个、二十个或者更多的应用。 Django如何区分它们URL的名字呢? 例如,polls 应用具有一个detail 视图,相同项目中的博客应用可能也有这样一个视图。当使用模板标签{% url %}时,人们该如何做才能使得Django知道为一个URL创建哪个应用的视图?
- 答案是在你的主URLconf下添加命名空间。 在mysite/urls.py文件中,添加命名空间将它修改成:
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^polls/', include('polls.urls', namespace="polls")),
url(r'^admin/', include(admin.site.urls)),
]
现在将你的模板polls/index.html修改为指向具有命名空间的详细视图:
- polls/templates/polls/index.html
<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
- polls/templates/polls/detail.html
<h1>{{ question.question_text }}</h1>
<ul>{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>