zoukankan      html  css  js  c++  java
  • django实例:创建你的第一个应用投票系统(4)前台页面

    现在已经可以在后台管理投票了,现在就差怎么在前台显示和如何投票了
    1、index:首先第一个要有首页,用来显示所有的投票
    2、detail:详细信息页面,用来显示一个投票及相应的选项
    3、results:结果页面,用来查看一个投票的结果
    以及一个投票的操作

    在polls/views.py 页面添加如下代码

    from django.http import HttpResponse
    def index(request):
        return HttpResponse("Hello, world. You're at the poll index.")

    打开polls/urls.py,设置如下url路由信息

    from django.conf.urls import patterns, url
    from polls import views
    urlpatterns = patterns('',
        url(r'^$', views.index, name='index')
    )

    打开项目下面的urls.py 即mysite/urls.py 用把poll应用下的url包含到主urls配置里面。

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

    打开http://localhost:8000/polls/ 测试一下看看。

    如果要想往views里面的方法传递参数要怎么做呢
    看看下面的
    修改poll/url.py

    from django.conf.urls import patterns, url
    from polls 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'),
    )

    在polls/views.py添加

    def detail(request, poll_id):
        return HttpResponse("You're looking at poll %s." % poll_id)
    def results(request, poll_id):
        return HttpResponse("You're looking at the results of poll %s." % poll_id)
    def vote(request, poll_id):
        return HttpResponse("You're voting on poll %s." % poll_id)

    如果在浏览器输入http://localhost:8000/polls/34/,django是怎么处理的呢
    1、在mysite/url.py中先找到匹配的 '^polls/'
    2、把匹配的url去掉,把剩余 ”34/" 传递给poll下面的url.py
    3、在poll/url.py中找到匹配的项 r'^(?P<poll_id>\d+)/$' 执行相应的view : detail()
    在执行detail()的时候相当于

    detail(request=<HttpRequest object>, poll_id='34')

    那么这个34是如何对应到poll_id呢
    在上面的第三步中,r'^(?P<poll_id>\d+)/$' 会把匹配出来的内容 34 和你们的正则组对应起来,poll_id对应匹配到的34


    在上面写的index view仅仅是测试的,没有做具体的功能。

    from django.http import HttpResponse
    from polls.models import Poll
    def index(request):
        latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
        output = ', '.join([p.question for p in latest_poll_list])
        return HttpResponse(output)

    上面的意思是取最新的5个记录,以字符串的形式返回,并用“,”分开

    模板

    上面看到返回的内容的格式是直接写到index里面的,人们常用的要数据的逻辑处理和呈现分开就是这里的情况
    这就用到django的模板功能了
    建立文件:polls/templates/polls/index.html
    内容如下

    {% if latest_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))

    大概意思就是 先加载一个模板,设置一个字典数据,再用render方法把模板中和字典对应的变量用字典中的值处理

    因为django模板功能经常使用,所以提供了一种简化的代码写法。

    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)

    和上面是一样的意思

    404错误
    这个错误我们很常见,当对应的页面不存在的时候就会出来

    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})

    这里还没有说到polls/detail.html模板,所以先在建立这个文件,简单的写入如下代码,先不让他出错

    {{ poll }}

    如果在poll中对应的poll_id不存在的话就引发404错误。

    像这种情况会经常发生,所以django也提供了简单的写法

    1. from django.shortcuts import render, get_object_or_404
    2. # ...
    3. def detail(request, poll_id):
    4.     poll = get_object_or_404(Poll, pk=poll_id)
    5.     return render(request, 'polls/detail.html', {'poll': poll})
    复制代码

    如果是要处理多个对象需要用这个:

    get_list_or_404()

    get_object_or_404

    是一样的功能,只是处理对象不同

    如果发现错误了会在你的项目的url配置文件中找 handler404 对应的view来显示,如果找不到的话会用django自己的viewdjango.views.defaults.page_not_found()来显示,对于404文件也可以用模板来设置
    在项目模板中 mysite/templates 中添加404.html django会自动找到这个模板,并且显示出来。

    当然只有在DEBUG为false的情况下才会显示出现,否则会显示出一个具体的调试错误信息,可在settings.py文件里面设置


    现在继续模板,修改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对象中查找question ,如果找不能以属性的方式来查找,因为在这个例子里question 就是poll的属性,所以在这里就找到了,如果还找不到的话就以列表索引的方式来查找。

    poll.choice_set.all:这里其实执行的是poll.choice_set.all()方法,会返回 Choice 的迭代对象

    1. 模板中的url引用
    复制代码

    在上面代码中

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

    里面的url连接是直接写在模板里面的,如果poll应用所在的位置改变了,就得需要在所有用到的模板里面都修改修改。所以django有一种简单的方法来实现。
    还记得在poll/urls.py里设置的url吧。
    没错,注意在设置url的时候最后面有个 name 属性,这个属性就是来给每个url一个名字,可以在模板里面直接用这个名字来代替url

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

    注意:
    如果设置{% url 'detail' poll.id %}不正常,而{% url detail poll.id %} 正常的话,说明你用的django版本<1.5,需要在模板的最上面添加:

    {% load url from future %}

    在poll.urls.py里面是如下的定义

    1. # the 'name' value as called by the {% url %} template tag
    2. url(r'^(?P<poll_id>\d+)/$', views.detail, name='detail'),
    复制代码

    如果以后想要在其他地方应用,或者不同的目录结果中,只需要更改此处就可以了,不用在每个模板里面更改,是不是很简单

    # added the word 'specifics'
    url(r'^specifics/(?P<poll_id>\d+)/$', views.detail, name='detail'),

    url命名空间
    假如现在有两个应用,每个应用下面的urls.py里面都有一个detail 定义的url,这个时候django就没法判断要用哪个了,所以就出来了个命名空间。用来区别不同的url

    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)),
    )

    再修改下模板文件

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

    添加命名空间

    <li><a href="{% url 'polls:detail' poll.id %}">{{ poll.question }}</a></li>
  • 相关阅读:
    Spring Freamwork 开发初体验
    mybooklist.cn 书单de故事六月十六日
    mybooklist 日志5.12
    我的书单mybooklist
    Bison
    Java学习日记——基础篇(一)常识
    Python学习日记(十)—— 杂货铺(全局变量补充、Python参数传递、字符串格式化、迭代器、生成器)
    Python学习日记(九)—— 模块二(logging、json&pickle、xml、requests、configparser、shutil、subprocess)
    Python学习日记(八)—— 模块一(sys、os、hashlib、random、time、RE)
    Python学习日记(七)——装饰器
  • 原文地址:https://www.cnblogs.com/djangochina/p/3114269.html
Copyright © 2011-2022 走看看