• Django教程:第一个Django应用程序(3)


    Django教程:第一个Django应用程序(3)

     

    2013-10-08 磁针石

     

    #承接软件自动化实施与培训等gtalk:ouyangchongwu#gmail.comqq 37391319

    #博客:http://blog.csdn.net/oychw

    #版权所有,转载刊登请来函联系

    # 深圳测试自动化python项目接单群113938272深圳广州软件测试开发 6089740

    #深圳湖南人业务户外群 66250781武冈洞口城步新宁乡情群49494279

    #参考资料:https://docs.djangoproject.com/en/1.5/intro/tutorial01/

    # http://django-chinese-docs.readthedocs.org/en/latest/intro/tutorial01.html

    #本文的图片没有上传,完整的文档参见:python模块笔记:http://t.cn/z8ggk71

     

    本节关注创建公共界面 –视图(views)。

    哲学

    在 Django 应用中,视图是一“类”具有特定功能和模板的网页。 例如,在博客应用中,你可能会有以下视图:

    §  博客首页显示最新发表的博客。

    §  博客详细页面单个博客的固定连接。

    §  基于年份的归档页显示指定年份所有月份的博客。

    §  基于月份的归档页显示指定月份所有日期的博客。

    §  基于日期的归档页显示指定日期所有博客。

    §  评论为指定博客处理评论。

    在我们的投票应用中,将有以下四个视图:

    §  Poll“index” 显示最新投票。

    §  Poll“detail” 显示投票,无投票结果,但是可以投票

    §  Poll“results” 显示指定的投票结果。

    §  投票处理投票。

    在 Django 中,网页及其他内容是由视图展现。视图就是简单的 Python 函数(或方法)。Django 会通过检查URL(确切地说是域名之后的那部分 URL)来匹配一个视图。

    URL 模式是URL的通用形式- 比如: /newsarchive/<year>/<month>/.

    Django 通过‘URLconfs’把URL 模式 (正则表达式)映射到视图。本教程中介绍URLconfs 的基本指令,更多信息参见django.core.urlresolvers

    第一个视图

    编辑polls/views.py:

    from django.http importHttpResponse

     

    defindex(request):

        returnHttpResponse("Hello, world. You're at the poll index.")

    然后配置URLconf 。在 polls 目录下创建一个名为 urls.py 的 URLconf 文档。

    from django.conf.urls importpatterns,url

    from polls importviews

    urlpatterns=patterns('',

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

    )

    配置 mysite/urls.py 调用polls.urls:

     

    fromdjango.conf.urls import patterns, include, url

    fromdjango.contrib import admin

    admin.autodiscover()

    urlpatterns= patterns('',

        url(r'^polls/', include('polls.urls')),

        url(r'^admin/', include(admin.site.urls)),

    )

    启动开发服务器:python manage.py runserver 192.168.4.13:8000。访问:http://192.168.4.13:8000/polls/,将可以看到:Hello, world.You're at the poll index。

    现在你在 URLconf 中配置了 index 视图。通过浏览器访问 http://localhost:8000/polls/ ,如同你在 index 视图中定义的一样,你将看到“Hello, world. You’re at the poll index.” 文字。

    url() 两个必选参数: regex 和view, 两个可选参数:kwargs和name。

    regex是regularexpression 的简写,这是字符串模式匹配的语法,在 Django 中就是url 模式。 Django 将请求的URL 从上至下依次匹配列表中的正则表达式,直到匹配为止。

    注意这些正则表达式不会匹配 GET 和 POST 参数以及域名。 例如:针对请求http://www.example.com/myapp/,URLconf 将只查找 myapp/。而在http://www.example.com/myapp/?page=3 也是如此。

    当 Django 匹配了正则表达式就会调用响应的view函数, HttpRequest作为第一个参数和正则表达式 “捕获” 值的作为其他参数。 如果是简单正则捕获,将按顺序位置传参数;如果是命名正则捕获,将按关键字传参数值。

    kwargs任意关键字参数,可传一个字典至目标视图。

    Name:给你的URL取名,让你在 其他地方尤其是模板中可以更方便地引用它,特别是在模板中。 这一强大的功能可允许你通过一个文件就可修改项目中的全局URL 模式。

    更多视图

    现在我们再增加一些有参数的视图:

    defdetail(request, poll_id):

        return HttpResponse("You're looking atpoll %s." % poll_id)

     

    defresults(request, poll_id):

        return HttpResponse("You're looking atthe results of poll %s." % poll_id)

     

    defvote(request, poll_id):

        return HttpResponse("You're voting onpoll %s." % poll_id)

    添加对应的url映射:

    fromdjango.conf.urls import patterns, url

    frompolls import views

    urlpatterns= patterns('',

        # ex: /polls/

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

        # ex: /polls/5/

        url(r'^(?P<poll_id>d+)/$',views.detail, name='detail'),

        # ex: /polls/5/results/

        url(r'^(?P<poll_id>d+)/results/$',views.results, name='results'),

        # ex: /polls/5/vote/

        url(r'^(?P<poll_id>d+)/vote/$',views.vote, name='vote'),

    )

    在你的浏览器中访问 http://192.168.4.13:8000/polls/34/ 。将运行detail()方法并显示URL 中提供的ID 。/polls/34/results和/polls/34/vote/也有类似显示。

    访问网站页面时,比如/polls/34/时,Django 会加载mysite.urls模块(settings中的ROOT_URLCONF = 'mysite.urls'),然后找到urlpatterns变量并依次匹配正则表达式。include()表示导入其他 URL配置。include()中的正则表达式没有$(字符串结尾的匹配符),尾部是一个反斜杠。当 Django 解析include()时,它截取匹配部分而把剩余的字符串交由子URLconf 作进一步处理。这样include()使 URLs 即插即用。

    当用户访问 “/polls/34/”:

    §  Django 匹配'^polls/' 

    §  Django 截取匹配文本polls/发送34/ ‘polls.urls’ URLconf 后者匹配r'^(?P<poll_id>d+)/$' 导致如下调用

    detail(request=<HttpRequestobject>, poll_id='34')

    添加些实际的功能

    每个视图返回一个包含请求页面的内容HttpResponse对象或者抛出一个异常,例如 Http404

    视图可以选择是否读取数据库记录,是否使用Django或python第三方模板系统。视图可以生成PDF 文件,输出 XML ,创建 ZIP 文件等。可以使用任何 Python 库。

    下面index视图显示系统中最新发布的 5 个调查问卷,以逗号分割并按发布日期排序::

    fromdjango.http import HttpResponse

     

    from polls.modelsimport Poll

     

    def index(request):

       latest_poll_list = Poll.objects.order_by('-pub_date')[:5]

        output = ','.join([p.question for p in latest_poll_list])

        returnHttpResponse(output)

    通过模板可以分离python和设计。

    在polls目录下创建templates目录。Django 将会在那寻找模板。

    Django 的TEMPLATE_LOADERS配置中查找模板的方法。 django.template.loaders.app_directories.Loader 就会在INSTALLED_APPS的templates子目录下查找模板。

    在你刚创建的templates目录下,创建polls(防止不同应用有重名的模板)的目录,并在其中创建文件index.html。你的模板位于polls/templates/polls/index.html 。简写为polls/index.html就可。

    {% iflatest_poll_list %}

        <ul>

        {% for poll in latest_poll_list %}

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

        {% endfor %}

        </ul>

    {% else%}

        <p>No polls are available.</p>

    {%endif %}

    现在让我们在 index 视图中使用这个模板:

    from django.http import HttpResponse
    from django.template import Context, loader
     
    from polls.models import Poll
     
    def index(request):
        latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
        template = loader.get_template('polls/index.html')
        context = Context({
            'latest_poll_list': latest_poll_list,
        })
        return HttpResponse(template.render(context))

    代码将加载 polls/index.html 模板并传递 context。context是一个映射模板变量为Python 对象的字典。

    在你的浏览器中加载 “/polls/” 页,你应该看到一个列表,包含了在教程 第1部分 中创建的 “What’sup” 调查。而链接指向 poll 的具体页面。

          上述加载模板过程很常用,为此Django提供了快捷方式:render(),用于加载模板,填充上下文并返回一个含有模板渲染结果的HttpResponse对象。

    from django.shortcuts import render
     
    from polls.models import Poll
     
    def index(request):
        latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
        context = {'latest_poll_list': latest_poll_list}
        return render(request, 'polls/index.html', context)

    render() 函数中第一个参数是 request 对象,第二个参数是一个模板名称,第三个是一个字典类型的可选参数。它将返回根据给定模板和上下文渲染的HttpResponse对象。

    抛出 404 异常

    显示具体投票的视图detail:

    from django.http import Http404
    # ...
    def detail(request, poll_id):
        try:
            poll = Poll.objects.get(pk=poll_id)
        except Poll.DoesNotExist:
            raise Http404
        return render(request, 'polls/detail.html', {'poll': poll})

    poll 的 ID 不存在,视图将抛出Http404异常。我们稍后讨论如何设置polls/detail.html模板,若是你想快速运行上面的例子,在模板文件中添加如下代码:

    {{ poll }}

                同样这也有个快捷方式。

    from django.shortcuts import render, get_object_or_404
    # ...
    def detail(request, poll_id):
        poll = get_object_or_404(Poll, pk=poll_id)
        return render(request, 'polls/detail.html', {'poll': poll})

    get_object_or_404()使用Django 模型作为第一个参数,还有一些任意数量的传递到模型管理器的get()的关键字参数,若对象不存在时就抛出Http404异常。

    为什么不在更高层自动捕获 ObjectDoesNotExist异常, 或者由模型 API 抛出 Http404异常?

    因为那样会使模型层与视图层耦合在一起。保持松耦合Django 最重要的设计目标之一。一些耦合控制在 django.shortcuts 模块中介绍。

    get_list_or_404()get_object_or_404()类似– 不过执行的是 filter() 而不是 get() 。若返回的是空列表将抛出 Http404 异常。

    编写404 ( 页面未找到 ) 视图

    Django 载入特定的视图来处理 404 错误,根据你的 root URLconf (仅root URLconf)中设置的handler404变量来查找视图。

    一般不需要编写 404 视图。若没有设置handler404,默认使用内置的django.views.defaults.page_not_found()视图。或者在你的模板目录根目录

    编写一个 500 ( 服务器错误 ) 视图

    类似的,你可以在 root URLconf 中定义 handler500 变量,在服务器发生错误时调用对应的视图。视图代码产生的运行时错误会发生服务器错误。

    同样,在模板根目录下创建一个500.html模板并且添加些像“出错了”之类的内容。

    使用模板系统

    修改polls/detail.html :

    <h1>{{ poll.question }}</h1>
    <ul>
    {% for choice in poll.choice_set.all %}
        <li>{{ choice.choice_text }}</li>
    {% endfor %}
    </ul>

    模板系统使用了“变量.属性”的语法访问变量的属性值。 例如 {{ poll.question }} , 首先 Django 对 poll 对象做字典查询。 失败之后尝试属性查询 – 在本例中属性查询成功了。 如果属性查询失败将尝试列表索引查询。

    {% for %}循环中有方法调用: poll.choice_set.all即Python 代码poll.choice_set.all(),它将返回一组可迭代的Choice对象。

    更多模板的信息参见 templateguide 。

    移除模板中硬编码的 URLS

    polls/index.html中,polls/{{ poll.id }}等是硬编码:

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

    可以在 url 配置中使用 {% url %} 模板标记来移除特定的 URL 路径依赖:

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

    其原理就是在 polls.urls 模块中寻找指定的URL 定义。 你知道命名为 ‘detail’ 的 URL 就如下所示那样定义的一样::

    ...
    # 'name' 的值由 {% url %} 模板标记来引用
    url(r'^(?P<poll_id>d+)/$', views.detail, name='detail'),
    ...

    如果你想将 polls 的 detail 视图的 URL 改成polls/specifics/12,那不需要在模板(或者模板集)中修改而只要在 polls/urls.py 修改:

    ...
    # 新增 'specifics'
    url(r'^specifics/(?P<poll_id>d+)/$', views.detail, name='detail'),
    ...

    URL命名空间:

    如果多个应用都有名字为 detail的 视图,需要在 root URLconf 配置中添加命名空间。修改mysite/urls.py文件:

    from django.conf.urls import patterns, include, url
     
    from django.contrib import admin
    admin.autodiscover()
     
    urlpatterns = patterns('',
        url(r'^polls/', include('polls.urls', namespace="polls")),
        url(r'^admin/', include(admin.site.urls)),
    )

    修改polls/index.htm从:

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

    为包含命名空间的 detail 视图:

    <li><a href="{% url 'polls:detail' poll.id %}">{{ poll.question }}</a></li>
  • 相关阅读:
    【Java】String和Date、Timestamp之间的转换
    pl/sql改为汉语窗口的办法
    MySql生成随机数
    ETL概念
    oracle数据库中序列使用讲解
    oracle中的merge into用法解析
    mysql实现自动更新时间戳
    3.6:Linux touch命令:修改文件的时间戳
    3.5:Linux rmdir命令:删除空目录
    3.4:Linux mkdir命令:创建目录(文件夹)
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3357853.html
Copyright © 2020-2023  润新知