Django App(三) View+Template

       接着上一节(二)的内容,首先启动站点,通过界面添加Question和Choice两张表的数据,因为接下来,要向polls app里面添加views.

     1.添加数据如下(这里是通过界面操作添加的数据)

        Question

        

        Choice

        

     2.添加views

       编写polls/views.py,添加detail(指定question的详情),results(指定question的投票结果),vote(指定question投票),每个view指定question_id作为参数,添加如下代码: 

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

         实际上这里所说的view,就是指polls/views.py中定义的一个一个的函数(action),python中函数名要全小写,如果必须有大写,不会报错,但是在路由体系中,是大小写敏感的,如果url中有大写自动转换成小写,但是如果,在定义urls.py中出现大写的定义,该view就无法访问,这个在下面会验证,这里全部采用小写.接下来把新定义的view添加到polls/urls.py路由中:

1 from django.urls import path
2 from . import views
3 urlpatterns=[
4     path('first/',views.index,name='index'),
5     path('<int:question_id>/detail',views.detail,name="detail"), #定义detail view
6     path('<int:question_id>/results',views.results,name='results'),#定义格式:/参数[参数类型为int]/results
7     path('vote/<int:question_id>',views.vote,name='vote')  #定义格式:vote/参数[参数类型为int]
8 ]

           根据刚刚定义的路由格式,分别查看

           http://localhost:8008/polls/1/detail

           

            http://localhost:8008/polls/vote/1

           

           http://lcoalhost:8008/polls/vote/abce          

           

           接下来验证路由大小写的问题,修改polls/urls.py如下:

    #这里将原来的vote/<int:question_id>改成<Vote/<int:question_id>
    path('Vote/<int:question_id>',views.vote,name='Vote')  #定义格式:vote/参数[参数类型为int]

           http://localhost:8008/polls/vote/1   #url即使输入的有大写,也会自动转换成小写,所以在定义ulrs.py的时候 全部采用小写

           

         3.添加views模板

           上面用了大篇幅完成了向app polls中添加view(action),但是我们并不是每一次都希望view就返回一句话,更多时候我们需要他返回的是一个动态的,完整的页面

           接下来的事情,view的主要任务是负责准备页面需要展示的数据,而由模板负责数据绑定和页面渲染,模板和view一般是一对一的

           新建路径及文件 polls/templates/polls/index,现在polls目录如下:

           

           改造polls/views.py view index 如下: 

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

          通过上一节的配置,和本节开始部分的努力,models 中的Question的对象已经和数据库绑定,并且带有数据: 

 latest_question_list = Question.objects.order_by('-pub_date')[:5]  #按照pub_date排序,取前五条
 template = loader.get_template('polls/index.html')  #加载模板
 HttpResponse(template.render(context, request))   #使用loader填充数据

         编写polls/templates/polls/index.html如下:

{% if latest_question_list %}
    <ul>
    {% for question in latest_question_list %}
        <li><a href="/polls/{{ question.id }}/detail">{{ question.question_text }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No polls are available.</p>
{% endif %}

          在html中直接取出view中loader填充的数据:'latest_question_list': latest_question_list在界面循环展示出来

             

           在绑定数据到界面的时候,也可以使用render(),似乎更简洁,便捷polls/views.py:

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

          4.处理404的错误

             上面通过模板生成的每一连接,连接到 http://localhost:8000/polls/(question_id)/detail,如果传入的question_id在数据库中不存在,我们就要在代码中提前处理,编辑polls/views.py/detail 如下:

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

             官网后面还介绍了 Template System ,防止硬编码Url,Url命名空间等,请参考[https://docs.djangoproject.com/en/2.0/intro/tutorial03/

原文地址:https://www.cnblogs.com/andayhou/p/8339852.html