开始你的第一个django_part3

这次主要讲解views模块

接着前两节的例子继续,这里先总结一下前两节的内容,都快忘了

一个django程序,使用django-admin创建后,我们可以配置一个app,然后将app加入到settings.py文件里面,这里就涉及到使用settings.py文件,更详细的内容以后在记录,然后是同步数据库,运行开发服务器,进入shell后,对数据库的基本操作,包括问题和选项表的关联,后面一节学习了admin后台管理,包括数据筛选,models的布局等。

view就相当于一个web页,在django里面就是服务器的一个函数或者指定的模版

有点绕口,举个例子,一个博客应用程序,可能有下面几个views:

  1. 首页
  2. 详细页面
  3. 根据时间归档的页面(比如根据年,月,日归档)
  4. 一些通用的操作

那在我们这个投票系统里面呢,我们将有下面几个views:

  1. 首页index--显示最近几个投票问题
  2. 详细页detail--显示投票问题,以及一个可以投票的表单
  3. 结果页result--显示指定的投票的结果
  4. Vote action--投票动作页?

其实说白了,views里面的内容,就是几个函数而已,然后下节讲到的urls就使用这些函数,展示在html就对了。

URLconfs 这个有空回去看看

先来个hello world的

在polls/views.py里面加入一个函数,如下:

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world!")

 在我们的polls目录下面加入一个urls.py文件,这个文件必须要自己加

内容如下:

from django.conf.urls import patterns, url
from polls import views

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

这个里面的views.index就是访问刚刚的函数了,看看python的基本语法就懂了,name就是为这个页面取了一个名字,便于后续避免使用硬编码等问题出现。

在mysite这个根目录下面的ursl.py文件里面,代码如下:

from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'mysite.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),
    #url(r'index/', include('polls.urls')),
    url(r'^polls/', include('polls.urls')),
    url(r'^admin/', include(admin.site.urls)),
)

 当我们访问http://localhost:8000/polls/这个的时候就会在页面显示我们函数里面的东西了。

url里面的第一个参数就是匹配咋们服务器后面的字符串,我们这个例子就是8000端口后的了,正则表达式大家去看看,然后include里面就是需要在匹配的urls里面的urlpatterns变量。

接下来我们在views里面加入更多的内容:

from django.shortcuts import render
from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world!")

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)

 自然而然在我们的polls的urls.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'),
)

 访问看看吧。http://localhost:8000/polls/5 http://localhost:8000/polls/5/vote/  http://localhost:8000/polls/5/results/

可以看出来,http://localhost:8000/polls 这个是在根urls里面设置好了的,访问的时候必须有吧,使用(?P<poll_id>d+)就把我们的网址里面的5赋值给了poll_id这个变量,也就是我们在写函数的时候的形式参数。这个形式参数和(?P)里面这个参数必须一致,否则报错,不行就把vote函数里面的poll_id改为其它名字试试?

当我们访问这个:http://localhost:8000/polls/34/ 网站的时候,django先在根urls里面匹配到了^polls/这个,然后把34/传递给了polls目录下的urls.py文件,当然此时匹配到的是url(r'^(?P<poll_id>d+)/$', views.detail, name='detail')这个,所以执行views里面的detail函数,而且有poll_id参数传入进来。

其实就是detail(request=<HttpRequest object>, poll_id='34') 这样表达的。

每一个view做下面事情:

  1. 返回一个httpresponse对象,包含页面内容;
  2. 或者抛出一个异常,比如http404。

注意两个事情是或的关系

view可以做很多事情,比如下面这段英语描述的(自己翻译了)

Your view can read records from a database, or not. It can use a template system such as Django’s – or a third-party Python template system – or not. It can generate a PDF file, output XML, create a ZIP file on the fly, anything you want, using whatever Python libraries you want.

All Django wants is that HttpResponse. Or an exception.

Because it’s convenient, let’s use Django’s own database API, which we covered in Tutorial 1. Here’s one stab at a new index() view, which displays the latest 5 poll questions in the system, separated by commas, according to publication date:

我们按照要求,取出投票系统里面的问题,按照时间排序哈。当然目前我们里面就一个What's up问题吧。

修改index函数:

from django.shortcuts import render
from django.http import HttpResponse
from polls.models import Poll

def index(request):
    poll_list = Poll.objects.order_by('-pub_date')[0:5]
    output_list = ','.join(p.question for p in poll_list)
    return HttpResponse(output_list)
    #return HttpResponse("Hello, world!")

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/ 试试效果吧

数据少了,加一个问题试试。

加的方法很多,可以去shell里面加,看第一节内容,可以去admin后台管理里面加,看第二节内容,可以直接操作数据库嘛,这个自己研究吧。

本文加了一个test投票系统,没有任何选项。

在访问看看。

不错有效果。

试试模版功能,这里和官方英语教程有点不一样,我在polls目录下面建了一个templates目录,在下面加入了我的index.html文档,以后在说明这样做的方式。

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

 views.py文件内容:

from django.shortcuts import render
from django.http import HttpResponse
from polls.models import Poll
from django.template import RequestContext, loader


def index(request):
    # poll_list = Poll.objects.order_by('-pub_date')[0:5]
    # output_list = ','.join(p.question for p in poll_list)
    # return HttpResponse(output_list)
    #return HttpResponse("Hello, world!")
    latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
    template = loader.get_template('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)

 下面使用render简便方法,效果一样:

from django.shortcuts import render
from django.http import HttpResponse
from polls.models import Poll
from django.template import RequestContext, loader


def index(request):
    # poll_list = Poll.objects.order_by('-pub_date')[0:5]
    # output_list = ','.join(p.question for p in poll_list)
    # return HttpResponse(output_list)
    #return HttpResponse("Hello, world!")
    # latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
    # template = loader.get_template('index.html')
    # context = RequestContext(request, {
    #     'latest_poll_list': latest_poll_list,
    # })
    # return HttpResponse(template.render(context))
    latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
    context = {'latest_poll_list': latest_poll_list}
    return render(request, '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)

 抛出异常的很简单,自己看看英文的就可以了。

下面写写detail里面的内容吧,还是需要detail.html这个模版

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

 detail这个函数也改改:

from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from polls.models import Poll
from django.template import RequestContext, loader


def index(request):
    # poll_list = Poll.objects.order_by('-pub_date')[0:5]
    # output_list = ','.join(p.question for p in poll_list)
    # return HttpResponse(output_list)
    #return HttpResponse("Hello, world!")
    # latest_poll_list = Poll.objects.order_by('-pub_date')[:5]
    # template = loader.get_template('index.html')
    # context = RequestContext(request, {
    #     'latest_poll_list': latest_poll_list,
    # })
    # return HttpResponse(template.render(context))
    latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
    context = {'latest_poll_list': latest_poll_list}
    return render(request, 'index.html', context)



def detail(request, poll_id):
    poll = get_object_or_404(Poll, pk=poll_id)
    return render(request, 'detail.html', {'poll':poll})
    #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/1/ 试试效果

避免硬编码的说明:

我们改改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 %}

 {url 'urls匹配里面的name' 函数的参数}

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

这样如果,我们想把 url(r'^(?P<poll_id>d+)/$', views.detail, name='detail')

改为:url(r'^specifics/(?P<poll_id>d+)/$', views.detail, name='detail'),也不会有影响我们的html页面的了。

嗯也可以设置命名空间:

根目录的urls修改如下:

from django.conf.urls import patterns, include, url

from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'mysite.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),
    #url(r'index/', include('polls.urls')),
    url(r'^polls/', include('polls.urls', namespace='polls')),
    url(r'^admin/', include(admin.site.urls)),
)

 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>
        <!-- <li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li> -->
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

 下一节继续吧。

骑着毛驴看日出
原文地址:https://www.cnblogs.com/linsir/p/4533038.html