目录
MTV模型结构分布层级
视图层返回类型
- 简单文本
- 文件:通过ajax静态服务器对静态文件渲染
- html、css、js
- JSON格式数据:对前端比较有用
def detail(request, question_id):
return HttpResponse("You're looking at question %s." % question_id)
def results(request, question_id):
response = "You're looking at the results of question %s."
return HttpResponse(response % question_id)
def vote(request, question_id):
return HttpResponse("You're voting on question %s." % question_id)
路由配置
- url匹配
path('int:question_id/', views.detail, name='detail'),
其中int是数据类型,question_id是参数,调用到上边的detail函数
- url配置
在mysites/settings--->ROOT_URLCONF = 'mysites.urls'
from django.urls import path
from . import views
urlpatterns = [
# ex: /api01/
path('', views.index, name='index'),
# ex: /api01/5/
path('int:question_id/', views.detail, name='detail'),
# ex: /api01/5/results/
path('int:question_id/results/', views.results, name='results'),
# ex: /api01/5/vote/
path('int:question_id/vote/', views.vote, name='vote'),
]
当某人请求你网站的某一页面时——比如说, "/polls/34/" ,Django 将会载入 mysite.urls
模块,因为这在配置项 ROOT_URLCONF 中设置了。然后 Django 寻找名为 urlpatterns
变量并且按序匹配正则表达式。在找到匹配项 'polls/'
,它切掉了匹配的文本("polls/"
),将剩余文本——"34/"
,发送至 'polls.urls' URLconf 做进一步处理。在这里剩余文本匹配了 '<int:question_id>/'
,使得我们 Django 以如下形式调用 detail()
模板
每个视图必须要做的只有两件事:返回一个包含被请求页面内容的 HttpResponse 对象,或者抛出一个异常,比如 Http404 。至于你还想干些什么,随便你。
你的视图可以从数据库里读取记录,可以使用一个模板引擎(比如 Django 自带的,或者其他第三方的),可以生成一个 PDF 文件,可以输出一个 XML,创建一个 ZIP 文件,你可以做任何你想做的事,使用任何你想用的 Python 库。
Django 只要求返回的是一个 HttpResponse ,或者抛出一个异常。
因为 Django 自带的数据库 API 很方便,我们曾学过,所以我们试试在视图里使用它。我们在 index()
函数里插入了一些新内容,让它能展示数据库里以发布日期排序的最近 5 个投票问题,以空格分割:
from django.http import HttpResponse
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
output = ', '.join([q.question_text for q in latest_question_list])
return HttpResponse(output)
# Leave the rest of the views (detail, results, vote) unchanged
我们可以通过print输出对上边的代码进行分析
Templates模板层
遇到试图修改没有反应,应该考虑浏览器缓存
- 首先将自带的Templates删掉,并修改配置文件
- 编写视图
def index(request):
'''request 就是作为参数传递进来的请求对象'''
latest_question_list = Question.objects.order_by('pub_data')[:5]
template = loader.get_template('index.html')
context = {
'latest_question_list': latest_question_list,
}
return HttpResponse(template.render(context, request))
解释:loader.get_template('index.html')---->下载template模板中的index.html模板
return HttpResponse(template.render(context, request))--->将数据传到静态模板
- 静态模板设置
{% if latest_question_list %}
<ul>
{% for question in latest_question_list %}
<li><a href="{
{ question.id }}/">{
{ question.question_text }}</a></li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
- 路由配置:访问api01/study01
urlpatterns = [
path('study01/',views.index),
]
由此上看如果用HttpResponse比较繁琐,所以可以换个django已经做好的函数render
from django.shortcuts import render
from .models import Question
def index(request):
latest_question_list = Question.objects.order_by('pub_data')[:5]
context = {'latest_question_list': latest_question_list}
return render(request, 'index.html', context)
也能直接访问到这个地址
404异常抛出
接下来我们有了index数据,但是我们如果去访问数据的话,却没有数据,所以我们可以抛出一个访问不到页面的错误:404
- 视图编写
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, 'detail.html', {'question': question})
- 静态模板设置;
{
{ question }}
- 路由设置:访问---->8000:/study01/01/---->存在则真。不存在则返回:404:Question does not exist
urlpatterns = [
path('study01/',views.index),
path('study01/<int:question_id>/', views.detail, name='detail'),
]
404快捷函数:
- 一个快捷函数: [
get_object_or_404()
]
尝试用 get() 函数获取一个对象,如果不存在就抛出 Http404 错误也是一个普遍的流程。Django 也提供了一个快捷函数,下面是修改后的详情 detail()
视图代码:
from django.shortcuts import get_object_or_404, render
from .models import Question
# ...
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'detail.html', {'question': question})
使用模板系统
回过头去看看我们的 detail()
视图。它向模板传递了上下文变量 question
。下面是 polls/detail.html
模板里正式的代码:
<h1>{
{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{
{ choice.choice_text }}</li>
{% endfor %}
</ul>
还记得吗,我们在 polls/index.html
里编写投票链接时,链接是硬编码的:
<li><a href="/polls/{
{ question.id }}/">{
{ question.question_text }}</a></li>
问题在于,硬编码和强耦合的链接,对于一个包含很多应用的项目来说,修改起来是十分困难的。然而,因为你在 polls.urls
的 url()
函数中通过 name 参数为 URL 定义了名字,你可以使用 {% url %}
标签代替它:
detail在路由中
<li><a href="{% url 'detail' question.id %}">{
{ question.question_text }}</a></li>