Django L3 编写你的第一个Django应用

Django L3 编写你的第一个Django应用,第3部分

 

  Django使用叫做‘URLconfs’的配置来为URL匹配视图。 一个URLconf负责使用正则表达式将URL模式匹配到视图。

 

编写第一个视图

 

$ cat tasks/views.py
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.

def index(request):
    return HttpResponse("Hello, world. You're at the polls index.")

  

$ cat tasks/urls.py
#!/usr/bin/env python
#-*- coding: utf-8 -*-

__author__ = 'Ye Lin'
__date__ = '17-2-9'

from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^$' , views.index , name='index'),

]

 

$ cat ltest/urls.py | tail -8
from django.conf.urls import url , include
from django.contrib import admin

urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r'^tasks/',include('tasks.urls')),
]

  http://127.0.0.1:20001/tasks/ , 可以直接访问

 

url() 参数:

  regex

  kwargs

  name

 

$tasks/urls.py
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^$' , views.index , name='index'),
    url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
    # http://127.0.0.1:20001/tasks/1/results/
    url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
    # http://127.0.0.1:20001/tasks/1/vote/
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
]

  

编写拥有实际功能的视图

$cat tasks/views.py
def index(request):
    latest_question_list = Questions.objects.order_by('-pub_date')[:5]
    template = loader.get_template('tasks/index.html')
    context = RequestContext(request, {
        'latest_question_list': latest_question_list,
    })
    return HttpResponse(template.render(context))

  

$ cat tasks/templates/tasks/index.html 
{% if latest_question_list %}
    <ul>
    {% for question in latest_question_list %}
        <li><a href="/tasks/{{ question.id }}/">{{ question.question_text }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>

  

快捷方式render() 

$cat tasks/views.py 

def index(request):
    latest_question_list = Questions.objects.order_by('-pub_date')[:5]
    template = loader.get_template('tasks/index.html')
    '''
    context = RequestContext(request, {
        'latest_question_list': latest_question_list,
    })
    return HttpResponse(template.render(context))
    '''
    context = {'latest_question_list': latest_question_list}
    return render(request, 'polls/index.html', context)

  

引发404错误

$cat tasks/views.py 
def detail(request, question_id): try: question = Questions.objects.get(pk=question_id) except Questions.DoesNotExist: raise Http404("Question does not exist") return render(request, 'tasks/detail.html', {'question': question})

 

快捷方式:get_object_or_404*(

一种常见的习惯是使用get()并在对象不存在时引发Http404Django为此提供一个快捷方式。 下面是重写后的detail()视图:

$cat tasks/views.py
def index(request):
    latest_question_list = Questions.objects.order_by('-pub_date')[:5]
    template = loader.get_template('tasks/index.html')
    '''
    context = RequestContext(request, {
        'latest_question_list': latest_question_list,
    })
    return HttpResponse(template.render(context))
    '''
    context = {'latest_question_list': latest_question_list}
    return render(request, 'tasks/index.html', context)

  

使用模板

$ cat tasks/templates/tasks/detail.html 
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
    <li>{{ choice.choice_text }}</li>
{% endfor %}

  

移除模板中的硬编码urls

 

  请记住,当我们在polls/index.html模板中编写一个指向Question的链接时,链接中一部分是硬编码的:

    <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

  这种硬编码、紧耦合的方法有一个问题,就是如果我们想在拥有许多模板文件的项目中修改URLs,那将会变得很有挑战性。 然而,因为你在polls.urls模块的url()函数中定义了name 参数,你可以通过使用{% url %}模板标签来移除对你的URL配置中定义的特定的URL的依赖:

  <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

  它的工作原理是在polls.urls模块里查找指定的URL的定义。你可以看到名为‘detail’的URL的准确定义:

  ...
  # the 'name' value as called by the {% url %} template tag
  url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
  ...

  如果你想把polls应用中detail视图的URL改成其它样子比如 polls/specifics/12/,就可以不必在该模板(或者多个模板)中修改它,只需要修改 polls/urls.py

  ...
  # added the word 'specifics'
  url(r'^specifics/(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
  ...
 

带命名空间的URL

  

教程中的这个项目只有一个应用tasks在真实的Django项目中,可能会有五个、十个、二十个或者更多的应用。 Django如何区分它们URL的名字呢? 例如,polls 应用具有一个detail 视图,相同项目中的博客应用可能也有这样一个视图。当使用模板标签{% url %}时,人们该如何做才能使得Django知道为一个URL创建哪个应用的视图?

答案是在你的主URLconf下添加命名空间。 tasks/urls.py文件中,添加命名空间将它修改成:

mysite/urls.py
from django.conf.urls import include, url
from django.contrib import admin

urlpatterns = [
    url(r'^tasks/', include('polls.urls', namespace="tasks")),
    url(r'^admin/', include(admin.site.urls)),
]

现在将你的模板tasks/index.html由:

tasks/templates/tasks/index.html
<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

修改为指向具有命名空间的详细视图:

polls/templates/polls/index.html
<li><a href="{% url 'tasks:detail' question.id %}">{{ question.question_text }}</a></li>

 

posted @ 2017-02-09 20:18  ZSR0401  阅读(191)  评论(0编辑  收藏  举报