Python学习笔记(Django篇)——4、继续完善视图层

时间:2021-03-04 19:15:16
在demo/views.py中添加这些代码:
  1. def detail(request, question_id):
  2. returnHttpResponse("You're looking at question %s."% question_id)
  3. def results(request, question_id):
  4. response ="You're looking at the results of question %s."
  5. returnHttpResponse(response % question_id)
  6. def vote(request, question_id):
  7. returnHttpResponse("You're voting on question %s."% question_id)
 
在demo/urls.py中加入如下代码,对应url的访问规则:
  1. from django.conf.urls import url
  2. from.import views
  3. urlpatterns =[
  4. # ex: /polls/
  5. url(r'^$', views.index, name='index'),
  6. # ex: /polls/5/
  7. url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
  8. # ex: /polls/5/results/
  9. url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
  10. # ex: /polls/5/vote/
  11. url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
  12. ]
 
为了让request做点什么事情,在demo/views.py中添加这些代码:
  1. from django.http importHttpResponse
  2. from.models importQuestion
  3. def index(request):
  4. latest_question_list =Question.objects.order_by('-pub_date')[:5]
  5. output =', '.join([q.question_text for q in latest_question_list])
  6. returnHttpResponse(output)
 
为了不让view层的代码hard-code,我们使用django的template功能,在demo下创建一个名为templates的文件夹 在其下polls/templates/polls/index.html放入代码:
  1. {%if latest_question_list %}
  2. <ul>
  3. {%for question in latest_question_list %}
  4. <li><a href="/demo/{{ question.id }}/">{{ question.question_text }}</a></li>
  5. {% endfor %}
  6. </ul>
  7. {%else%}
  8. <p>No polls are available.</p>
  9. {% endif %}
 
在demo/views.py中也要修改,可以获得template的内容:
  1. from django.http importHttpResponse
  2. from django.template import loader
  3. from.models importQuestion
  4. def index(request):
  5. latest_question_list =Question.objects.order_by('-pub_date')[:5]
  6. template = loader.get_template('demo/index.html')
  7. context ={
  8. 'latest_question_list': latest_question_list,
  9. }
  10. returnHttpResponse(template.render(context, request))
 
启动服务后,可以看到页面是这样的: Python学习笔记(Django篇)——4、继续完善视图层 然后我们再来重写一些demo/views.py的方法:
  1. from django.shortcuts import render
  2. from.models importQuestion
  3. def index(request):
  4. latest_question_list =Question.objects.order_by('-pub_date')[:5]
  5. context ={'latest_question_list': latest_question_list}
  6. return render(request,'demo/index.html', context)
在新的重写里面,我们不需要引入loader和HttpResponse,用render方法替换之。
          当url链接中的id不存在的时候,启动404错误,就会给出提示,那么如何启动404错误呢? 首先,在demo/views.py中加入如下代码:
  1. from django.http importHttp404
  2. from django.shortcuts import render
  3. from.models importQuestion
  4. # ...
  5. def detail(request, question_id):
  6. try:
  7. question =Question.objects.get(pk=question_id)
  8. exceptQuestion.DoesNotExist:
  9. raiseHttp404("Question does not exist")
  10. return render(request,'demo/detail.html',{'question': question})
当然也要在demo/templates/demo/detail.html建如下代码
  还有一个比较快捷的办法是使用get_object_or_404()这个方法 把这段代码放入demo/views.py中
  1. from django.shortcuts import get_object_or_404, render
  2. from.models importQuestion
  3. # ...
  4. def detail(request, question_id):
  5. question = get_object_or_404(Question, pk=question_id)
  6. return render(request,'demo/detail.html',{'question': question})
除了get_object_or_404()外,还有get_list_or_404() 方法,也有类似的用途
        使用template system: 在demo/templates/demo/detail.html中添加以下代码:
  1. <h1>{{ question.question_text }}</h1>
  2. <ul>
  3. {%for choice in question.choice_set.all %}
  4. <li>{{ choice.choice_text }}</li>
  5. {% endfor %}
  6. </ul>
可以看到在question中多了choice中的内容
Python学习笔记(Django篇)——4、继续完善视图层        关于URL中的hardcode如何移去: 我们看到在demo/index.html中的代码长这个样子
  1. <li><a href="/demo/{{ question.id }}/">{{ question.question_text }}</a></li>
这个‘demo’实在是太难看了,我们要想办法移去,替换成:
  1. <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
在demo/urls中可以看到如下代码:
  1. ...
  2. # the 'name' value as called by the {% url %} template tag
  3. url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
  4. ...
不过我们希望在链接中加入“specifics”,这样可以更好地说明这是显示的是它的detail,那么就改成:
  1. ...
  2. # added the word 'specifics'
  3. url(r'^specifics/(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
  4. ...
 
      在URL中添加名字空间,避免不同的app的url冲突: 在demo/urls.py下面添加app_name:
  1. from django.conf.urls import url
  2. from.import views
  3. app_name ='demo'
  4. urlpatterns =[
  5. url(r'^$', views.index, name='index'),
  6. url(r'^(?P<question_id>[0-9]+)/$', views.detail, name='detail'),
  7. url(r'^(?P<question_id>[0-9]+)/results/$', views.results, name='results'),
  8. url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
  9. ]
然后把demo/index.html中的如下代码:
  1. <li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>
改为:
  1. <li><a href="{% url 'demo:detail' question.id %}">{{ question.question_text }}</a></li>
这样在template中调用url的时候就不会发生命名冲突了