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 Http404
from django.shortcuts import render
from .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, render
def 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, render
from django.urls import reverse
from django.views import generic
from .models import Choice, Question
class 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 = Question
template_name = 'polls/detail.html'
class ResultsView(generic.DetailView):
model = Question
template_name = 'polls/results.html'
刷新后的界面如下
出现这种情况是,vote的数据没有插入进去造成的,也就是没有选项记录
可以通过下面进行插入动作
from polls.models import Choice, Question
Question.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的操作。请可以根据自己的提示练习一下;)