Django 实战3
1周前

Django实战2回顾
编写更多的views,在views.py添加下面代码
def index(request):return HttpResponse("你好,欢迎来到大成django 实践1")def detail(request, question_id):return HttpResponse("您正查看的问题是:%s." % question_id)def results(request, question_id):response = "您查看的问题结果是:%s."return HttpResponse(response % question_id)def vote(request, question_id):return HttpResponse("邀请你回答这个问题:%s." % question_id)
并且给它加上paths polls/urls.py
# ex: /polls/5/ path('<int:question_id>/', views.detail, name='detail'), # ex: /polls/5/results/ path('<int:question_id>/results/', views.results, name='results'), # ex: /polls/5/vote/ path('<int:question_id>/vote/', views.vote, name='vote'),这时候直接运行python manage.py runserver index是会提示错误的,错误如下

提示是没有index,那么就需要建立一个html页面
建立Index页面
接下来,在刚刚创建的templates目录中,创建另一个名为polls的目录,并在其中创建一个名为index.html. 换句话说,模板应该位于polls/templates/polls/index.html. 由于app目录模板加载器的工作方式如上所述,您可以在Django中将此模板称为polls/index.html.
index.html内容如下
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>index</title></head><body><!-这里是django的语法,类似jsp-->{% if latest_question_list %} <ul> {% for question in latest_question_list %} <li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li> {% endfor %} </ul>{% else %} <p>No polls are available.</p>{% endif %}</body></html>注意:模板命名空间
现在我们可以直接将模板放在polls/templates中(而不是创建另一个polls子目录),但这实际上是个坏主意。Django将选择它找到的第一个名称匹配的模板,如果在不同的应用程序中有同名的模板,Django将无法区分它们。我们需要能够将Django指向正确的一个,而确保这一点的最佳方法是给它们命名。也就是说,将这些模板放在另一个为应用程序本身命名的目录中。
页面有了index.html 需要建内容填写上去,也就是说还需要修改views.py这个类文件,将相关字段辅助进去
from django.http import HttpResponsefrom django.template import loaderfrom .models import Questiondef index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] template = loader.get_template('polls/index.html') context = { 'latest_question_list': latest_question_list, } return HttpResponse(template.render(context, request))第8行,可以看出,实际是容器赋值到了latest_question_list里面,在html页面中通过if判断latest_question_list是否为空,如果不为空,进行循环获取里面的值。
还有用到了render,render()
加载模板、填充上下文并返回带有呈现模板结果的HttpResponse对象是一种非常常见的习惯用法。Django提供了一个快捷方式。下面是完整的index()视图,重写如下:
def index(request): latest_question_list = Question.objects.order_by('-pub_date')[:5] context = {'latest_question_list': latest_question_list} return render(request, 'polls/index.html', context)上面只是写了显示5行记录[:5],页面效果如下
django detail页面
上面讲到了,index页面,知道了页面需要查看问题的明细,怎么做呢?
先把polls/views.py 修改为
from django.http import Http404from django.shortcuts import renderfrom .models import Question# ...def detail(request, question_id):try:question = Question.objects.get(pk=question_id)except Question.DoesNotExist:raise Http404("Question does not exist")return render(request, 'polls/detail.html', {'question': question})
发现还缺个detail.html的页面。那么就创建它polls/templates/polls/detail.html
{{ question }}点击问题的list 某行,就会弹出一个页面如
页面详情还是提供不多的信息,还需要修改页面,字体变了一下;)
编写一个最小的提交页面
修改polls/detail.html
<h1>{{ question.question_text }}</h1>{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}<form action="{% url 'polls:vote' question.id %}" method="post">{% csrf_token %}{% for choice in question.choice_set.all %}<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}"><label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>{% endfor %}<input type="submit" value="Vote"></form>
页面如果没有关,刷新一下会提示错误,没有关系还没有做完Vote
先第一个一个结果results.html
from django.shortcuts import get_object_or_404, renderdef results(request, question_id):question = get_object_or_404(Question, pk=question_id)return render(request, 'polls/results.html', {'question': question})
results.html内容如下
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>results</title></head><body><h1>{{ question.question_text }}</h1><ul>{% for choice in question.choice_set.all %}<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>{% endfor %}</ul><a href="{% url 'polls:detail' question.id %}">Vote again?</a></body></html>
重新修改urls.path
path('', views.IndexView.as_view(), name='index'), path('<int:pk>/', views.DetailView.as_view(), name='detail'), path('<int:pk>/results/', views.ResultsView.as_view(), name='results'), path('<int:question_id>/vote/', views.vote, name='vote'),增加*View
from django.shortcuts import get_object_or_404, renderfrom django.urls import reversefrom django.views import genericfrom .models import Choice, Questionclass IndexView(generic.ListView):template_name = 'polls/index.html'context_object_name = 'latest_question_list'def get_queryset(self):"""Return the last five published questions."""return Question.objects.order_by('-pub_date')[:5]class DetailView(generic.DetailView):model = Questiontemplate_name = 'polls/detail.html'class ResultsView(generic.DetailView):model = Questiontemplate_name = 'polls/results.html'
刷新后的界面如下
出现这种情况是,vote的数据没有插入进去造成的,也就是没有选项记录
可以通过下面进行插入动作
from polls.models import Choice, QuestionQuestion.objects.all()Question.objects.filter(id=3)q = Question.objects.get(pk=3)print(q.choice_set.all())q.choice_set.create(choice_text='Not much', votes=0)q.choice_set.create(choice_text='The sky', votes=0)c = q.choice_set.create(choice_text='Just hacking again', votes=0)print(q.choice_set.all())print(q.choice_set.count())
效果如下:
点击选择项,就进行了投票记录,

总结
学习一下数据库的crud的操作。请可以根据自己的提示练习一下;)
