zoukankan      html  css  js  c++  java
  • Django入门笔记【三】

    入门笔记翻译整理自:https://docs.djangoproject.com/en/1.8/

    *该笔记将使用一个关于投票网络应用(poll application)的例子来阐述Django的用法。

    Public interface - views.

    1. 定义

    视图(View)是Django应用中用于实现某一特定功能的Web页面。比如,一个博客可以有博客展示页面,博客创建页面,评论页面。

    2. 视图示例

    写入代码

    1 #polls/views.py
    2 
    3 from django.http import HttpResponse
    4 
    5 def index(request):
    6     return HttpResponse("Hello, world. You're at the polls index.")

    为了调用视图,我们需要将它映射到一个URL上,因此在polls目录下创建urls.py,最终目录结构如图所示

    1 polls/
    2     __init__.py
    3     admin.py
    4     models.py
    5     tests.py
    6     urls.py
    7     views.py

    在polls/urls.py中添加以下代码

    1 # polls/urls.py
    2 
    3 from django.conf.urls import url
    4 
    5 from . import views
    6 
    7 urlpatterns = [
    8     url(r'^$', views.index, name='index'),
    9 ]

    将根目录中的URLconf定位至polls/urls中,使用include()方法:

    1 # mysite/urls.py
    2 
    3 from django.conf.urls import include, url
    4 from django.contrib import admin
    5 
    6 urlpatterns = [
    7     url(r'^polls/', include('polls.urls')),
    8     url(r'^admin/', include(admin.site.urls)),
    9 ]

    现在可以通过http://localhost:8000/polls/进入polls应用的视图。

    url()方法有四个参数,必填两个:regex, view;选填两个:kwargs, name。其中,regex对模式(pattern)进行匹配,不区分GET和POST;完成匹配后,Django会调用view函数,并将HttpRequest和其他参数传入view函数中;kwargs将关键字参数传入view函数中;name可以对URL 命名

    3. 更多视图示例

    向polls/views.py中添加更多视图,和前面不同,这些视图需要接收参数

     1 # polls/views.py
     2 
     3 def detail(request, question_id):
     4     return HttpResponse("You're looking at question %s." % question_id)
     5 
     6 def results(request, question_id):
     7     response = "You're looking at the results of question %s."
     8     return HttpResponse(response % question_id)
     9 
    10 def vote(request, question_id):
    11     return HttpResponse("You're voting on question %s." % question_id)

    将这些视图映射到polls.urls

     1 # polls/urls.py
     2 
     3 from django.conf.urls import url
     4 
     5 from . import views
     6 
     7 urlpatterns = [
     8     # ex: /polls/
     9     url(r'^$', views.index, name='index'),
    10     # ex: /polls/5/
    11     url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
    12     # ex: /polls/5/results/
    13     url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
    14     # ex: /polls/5/vote/
    15     url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
    16 ]

    Django实现视图的逻辑如下,以用户访问"/polls/34/"为例:

    首先,Django寻找'^polls/'的相应匹配;

    然后,Django会剥离匹配的字符串"polls/",同时将剩下的文本"34/"发送至'polls.urls';

    最后,在'polls.urls'的URLconf中进一步匹配r'^(?P<question_id>[0-9]+)/$',并调用detail()视图。

    4. 视图再举例

    每一个视图都必须完成两个事件之一:返回HttpResponse,或者Http404。其余取决于应用需求。

     1 # polls/views.py
     2 
     3 from django.http import HttpResponse
     4 
     5 from .models import Question
     6 
     7 def index(request):
     8     latest_question_list = Question.objects.order_by('-pub_date')[:5]
     9     output = ', '.join([p.question_text for p in latest_question_list])
    10     return HttpResponse(output)
    11 # Leave the rest of the views (detail, results, vote) unchanged

    但是这里有一个问题,视图页面是硬编码的(hard-coded)。推荐将模板和Python代码独立。

    首先,创建polls/templates目录。Django会在该目录下寻找模板。TEMPLATES设置中的默认后台DjangoTemplates会在每个INSTALLED_APP下寻找templates子目录。

    然后,创建polls/templates/polls/index.html。这里创建第二个polls子目录的目的在于,区分不同应用下相同名称的index.html文件。

    接着,修改index.html文件

     1 # polls/templates/polls/index.html
     2 
     3 {% if latest_question_list %}
     4     <ul>
     5     {% for question in latest_question_list %}
     6         <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>
     7     {% endfor %}
     8     </ul>
     9 {% else %}
    10     <p>No polls are available.</p>
    11 {% endif %}

    最后,修改polls/views.py文件

     1 # polls/views.py
     2 
     3 from django.http import HttpResponse
     4 from django.template import RequestContext, loader
     5 
     6 from .models import Question
     7 
     8 
     9 def index(request):
    10     latest_question_list = Question.objects.order_by('-pub_date')[:5]
    11     template = loader.get_template('polls/index.html')
    12     context = RequestContext(request, {
    13         'latest_question_list': latest_question_list,
    14     })
    15     return HttpResponse(template.render(context))

    该代码加载polls/index.html,并将context传递给它。Context是映射模板变量到Python对象的字典。

    render()方法可以简化代码

     1 # polls/views.py
     2 
     3 from django.shortcuts import render
     4 
     5 from .models import Question
     6 
     7 
     8 def index(request):
     9     latest_question_list = Question.objects.order_by('-pub_date')[:5]
    10     context = {'latest_question_list': latest_question_list}
    11     return render(request, 'polls/index.html', context)

    5. 抛出404错误

    通过detail视图来示范实现

     1 # polls/views.py
     2 
     3 from django.http import Http404
     4 from django.shortcuts import render
     5 
     6 from .models import Question
     7 # ...
     8 def detail(request, question_id):
     9     try:
    10         question = Question.objects.get(pk=question_id)
    11     except Question.DoesNotExist:
    12         raise Http404("Question does not exist")
    13     return render(request, 'polls/detail.html', {'question': question})

    同时对polls/detail.html进行修改

    1 # polls/templates/polls/detail.html
    2 
    3 {{ question }}

    使用get_object_or_404()进行代码简化

    1 #polls/views.py
    2 
    3 from django.shortcuts import get_object_or_404, render
    4 
    5 from .models import Question
    6 # ...
    7 def detail(request, question_id):
    8     question = get_object_or_404(Question, pk=question_id)
    9     return render(request, 'polls/detail.html', {'question': question})

     6. 使用模板系统

    考虑context变量,对polls/detail.html进行修改

    1 # polls/templates/polls/detail.html
    2 
    3 <h1>{{ question.question_text }}</h1>
    4 <ul>
    5 {% for choice in question.choice_set.all %}
    6     <li>{{ choice.choice_text }}</li>
    7 {% endfor %}
    8 </ul>

    7. 移除模板中的硬编码URL

    比如polls/index.html,原代码不利于修改:

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

    改进为:

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

    这样改进过后,对URL的修改会变得很容易,比如,把以下代码

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

    改为

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

    8. URL命名空间

    一个项目里往往有很多应用,如果两个应用都有叫做detail的视图,Django会怎么区分它们的URL名称呢?答案是mysite/urls.py中可以添加命名空间到URLconf。比如:

    1 # mysite/urls.py
    2 
    3 from django.conf.urls import include, url
    4 from django.contrib import admin
    5 
    6 urlpatterns = [
    7     url(r'^polls/', include('polls.urls', namespace="polls")),
    8     url(r'^admin/', include(admin.site.urls)),
    9 ]

    同时将polls.index.html从

    1 # polls/templates/polls/index.html
    2 
    3 <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

    修改为

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

    --The End--

  • 相关阅读:
    今天到了1000分了,庆祝一下
    中文vs2008安装 mvc 1
    火车采集器使用感受
    存储过程中的case用法
    作为开发者的反思
    什么是程序员的优秀品质?
    遇到了乱码的问题(转载)
    利用网址导航站点推广
    国内优秀网址导航站总结 (转载)
    Unable to read local eventlog错误解决(转载)
  • 原文地址:https://www.cnblogs.com/py-drama/p/4582034.html
Copyright © 2011-2022 走看看