django (六) 第一个django app 创建views

在Django,网页和其他内容通过views来进行交互。每个视图都通过一个简单的Python函数(或方法)来展示。Django将通过检查请求的URL来选择一个视图(更精确地说是域名后面的URL)。从URL到View的过程是通过URLconfs来控制的。

接下来让我们写一个view。首先打开polls/views.py,添加如下代码:

# -*- coding: utf-8 -*-
from django.http import HttpResponse
def index(request):
    return HttpResponse("Hello, world. You’re at the poll index.")

接下来打开在polls文件夹下新建一个urls.py文件,建立view和url的联系,代码如下:

# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url
from polls import views
urlpatterns = patterns('',
    url(r'^$', views.index, name='index')
)

然后打开mysite/urls.py,添加代码如下:

urlpatterns = patterns('',
    url(r'^polls/', include('polls.urls')),
    url(r'^admin/', include(admin.site.urls)),
)

注意一下,所有的html文件都要保存为utf-8格式。

现在你就有一个Poll的主页了,进入http://127.0.0.1:8000/polls/.

下面我们来分析一下这行代码:

url(r'^$', views.index, name='index')
url有两个固定参数,正则表达式和view,另外还有两个可选的这里暂不做介绍。
接下来让我们在polls/view.py里添加更多的方法。不过和之前的有所不同,他们多了一个变量。代码如下:
# -*- coding: utf-8 -*-
from django.http import HttpResponse
def index(request):
    return HttpResponse("Hello, world. You’re at the poll index.")

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)
View Code

然后在polls/url.py里添加下面的代码:

import sys
from django.conf.urls import patterns, url
from polls import views
reload(sys)
sys.setdefaultencoding('utf-8')
urlpatterns = patterns('',
    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'),
)
View Code

请在在网页里依次的试一试吧!

好的,下面我们将继续完善,首先修改polls/views.py的index方法,完整代码如下:

# -*- coding: utf-8 -*-
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)

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)
View Code

Ok,页面变得不一样了,但是,这样修改外观时并不是很直观,为了使代码和外观分离,我们在template里面去改变它。

这里我们在polls目录下新建一个templates,在templates里再建一个目录polls,在他下面新建一个index.html。

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 %}
View Code

然后重新修改polls/view.py如下:

# -*- coding: utf-8 -*-
from django.http import HttpResponse
from django.template import RequestContext, 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 = RequestContext(request,{'latest_poll_list':latest_poll_list,})
    return HttpResponse(template.render(context))

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)
View Code

效果如下:

context 和 render经常成双出现,下面介绍一种更简便的写法:

修改polls/view。py如下:

# -*- coding: utf-8 -*-
from django.shortcuts import render

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

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)
View Code

ok.接下来完成views.py下的另外几个功能,首先是根据指定polls的id号找到那个Poll,找不到会出现404错误,页面全部代码如下:

# -*- coding: utf-8 -*-
from django.shortcuts import render
from django.http import Http404

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

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

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)
View Code

在polls下新建detail.html

这里暂时先临时写一个,往里面添加:

{{ poll }}

同样,关于404和get也有个简写组合,详细代码如下:

# -*- coding: utf-8 -*-
from django.shortcuts import render, get_object_or_404
from polls.models import Poll

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

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

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)
View Code

404的页面只能在根UROconf去加载,在各自的应用下加载无效。所以接下来在Root模板文件夹下(mysite/templates)新建404.html。

现在随便给404.html添加一些内容:

<h1>Page not found</h1>

<p>Sorry, but the requested page could not be found.</p>

如果你的程序处于调试状态,那么404页面永远不会显示,取而代之只会显示traceback。想改变调试状态可以在setting.py里去修改(第一行代码就是)。

DEBUG = False

注意一旦你关闭DEBUG模式,你必须给ALLOWED_HOSTS变量指定特定的值,这个根据需要而定,这里暂时设为:

ALLOWED_HOSTS = ['127.0.0.1']

 接下来,我们写一个500(server error)的界面,同上,在相同位置创建一个500.html内容自己随便写。

之前我们的detail.html只显示poll的信息,没有具体的choice的信息,现在我们把它添加进去。编辑detail.html:

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

关于choice_set的解释请看这篇文章:

http://www.cnblogs.com/freeggache/articles/4441715.html

可以刷新页面,去看看效果。

现在来讨论一下这行代码:

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

这里/polls/属于hardcoded风格,摒弃,可以采取下面这种方式:

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

完整index.html的代码如下:

{% if latest_poll_list %}
    <ul>
    {% for poll in latest_poll_list %}
        <li><a href="{% url 'detail' poll.id %}">{{ poll.question }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}
View Code

这样的话,如果你以后想修改URL比如说polls/specifics/12/你不用在模板里面去修改,你只需要在polls/urls.py离去修改:

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

现在,我们polls应用程序已经搭建起来了,那么如何区分polls应用程序和其他应用程序的url呢?就比如上面的detail,为了解决这个问题,django引进了namespace,首先修改你的mysite/urls.py:

# -*- coding: utf-8 -*-
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.html模板如下:

{% if latest_poll_list %}
    <ul>
    {% for poll in latest_poll_list %}
        <li><a href="{% url 'polls:detail' poll.id %}">{{ poll.question }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

 

posted @ 2015-04-19 17:51  坐观云起时  阅读(488)  评论(0编辑  收藏  举报