视图
视图 - 是具体的业务代码
在 app 下的 views.py 文件中编写代码
from django.http import HttpResponse
def index(request):
return HttpResponse("这里是我的站点")
为了调用该视图,我们还需要编写urlconf,也就是路由配置。在polls目录中新建一个文件,名字为urls.py(不要换成别的名字),在其中输入代码如下:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
接下来,在项目的主urls.py文件中添加urlpattern条目,指向我们刚才建立的polls这个app独有的urls.py文件,这里需要导入include模块。打开mysite/urls.py文件,代码如下:
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]
include语法相当于多级路由,它把接收到的url地址去除与此项匹配的部分,将剩下的字符串传递给下一级路由 urlconf
进行判断。
include的背后是一种即插即用的思想。项目的根路由不关心具体app的路由策略,只管往指定的二级路由转发,实现了应用解耦。app所属的二级路由可以根据自己的需要随意编写,不会和其它的app路由发生冲突。app目录可以放置在任何位置,而不用修改路由。这是软件设计里很常见的一种模式。
建议:除了admin路由外,尽量给每个app设计自己独立的二级路由。
路由设置成功后,启动服务器,然后在浏览器中访问地址
http://localhost:8000/polls/。
模板
Django 中的视图的概念是一类具有相同功能和模板的网页的集合。一个视图通常对应一个页面,提供特定的功能,使用特定的模板。
在Django中,网页和其它的一些内容都是通过视图来处理的。视图其实就是一个简单的Python函数(在基于类的视图中称为方法)。Django通过对比请求的URL地址来选择对应的视图,也就是路由。
为了将 URL 和视图关联起来,Django 使用 URLconfs来配置路由。
urlpatterns = [
path("", views.index, name="index"),
path("<int:question_id>/", views.detail, name="detail"),
path("<int:question_id>/results/", views.results, name="results"),
path("<int:question_id>/vote/", views.vote, name="vote"),
]
“int:question_id/”, 这里面不能包含空格
项目settings.py
文件中的 TEMPLATES
配置项描述了 Django 如何载入和渲染模板。默认的设置文件设置了 DjangoTemplates
后端作为模板引擎,并将 APP_DIRS
设置成了 True。这一选项将会让 DjangoTemplates 在每个 INSTALLED_APPS
文件夹中寻找 “templates” 子目录。
在templates目录下建立一个与app同名的子目录,将该app所属的模板都放到里面,从而达到独立命名空间的作用,不会出现引用错误。
返回模板的两种方法
from django.http import HttpResponse
from django.template import loader
from .models import Question
def 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))
from django.shortcuts import render
from .models import Question
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)
注意,此处不再需要导入 loader,而是从django.shortcuts导入了render。
render()函数的第一个位置参数是请求对象(就是view函数的第一个参数),这个参数是固定写法,不需要变动。第二个位置参数是模板文件。还可以有一个可选的第三参数,一个字典,包含需要传递给模板的数据。最后render函数返回一个经过字典数据渲染过的模板封装而成的HttpResponse对象。
返回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, 'polls/detail.html', {'question': question.question_text})
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, 'polls/detail.html', {'question': question})
get_object_or_404()
方法将一个Django模型作为第一个位置参数,后面可以跟上任意数量的关键字参数,如果对象不存在则弹出Http404错误。
同样,还有一个get_list_or_404()
方法,和上面的get_object_or_404()
类似,只不过是用来替代filter()
函数,当查询列表为空时弹出404错误。(filter是模型API中用来过滤查询结果的函数,它的结果是一个列表集。而get则是查询一个结果的方法,和filter是一个和多个的区别!)
为什么我们使用辅助函数get_object_or_404()
而不是自己捕获ObjectDoesNotExist
异常呢?还有,为什么模型 API 不直接抛出ObjectDoesNotExist
而是抛出 Http404
呢?因为这样做会增加模型层和视图层的耦合性。指导 Django 设计的最重要的思想之一就是要保证松散耦合。一些受控的耦合将会被包含在django.shortcuts
模块中。
在 {% for %}
循环中的方法调用——question.choice_set.all
其实就是Python的代码question.choice_set.all()
,它将返回一组可迭代的Choice对象,并用在{% for %}标签中。
删除模板中硬编码的URLs
此处的 app 名以 polls 为例
在 templates/polls/index.html文件中,还有一部分硬编码存在,也就是href里的“/polls/”部分:
它对于代码修改非常不利。设想如果你在urls.py文件里修改了路由表达式,那么你所有的模板中对这个url的引用都需要修改,这是无法接受的!
我们给urls定义了一个name别名,可以用它来解决这个问题。具体代码如下:
<li>
<a href="{% url 'detail' question.id %}">
{{ question.question_text }}
</a>
</li>
Django会在polls.urls文件中查找name='detail’的路由,具体的就是下面这行:
path('<int:question_id>/', views.detail, name='detail'),
举个栗子,如果你想将polls的detail视图的URL更换为polls/specifics/12/,那么你不需要在模板中重新修改url地址了,仅仅只需要在polls/urls.py文件中,将对应的正则表达式改成下面这样的就行了,所有模板中对它的引用都会自动修改成新的链接:
# 添加新的单词'specifics'
path('specifics/<int:question_id>/', views.detail, name='detail'),
URL names的命名空间
可以在polls/urls.py文件的开头部分,添加一个app_name的变量来指定该应用的命名空间:
from django.urls import path
from . import views
app_name = 'polls' # 重点是这一行
urlpatterns = [
path('', views.index, name='index'),
path('<int:question_id>/', views.detail, name='detail'),
path('<int:question_id>/results/', views.results, name='results'),
path('<int:question_id>/vote/', views.vote, name='vote'),
]
现在,让我们将代码修改得更严谨一点,将templates/polls/index.html中的
<li>
<a href="{% url 'detail' question.id %}">
{{ question.question_text }}
</a>
</li>
修改为:文章来源:https://www.toymoban.com/news/detail-847481.html
<li>
<a href="{% url 'polls:detail' question.id %}">
{{ question.question_text }}
</a>
</li>
文章来源地址https://www.toymoban.com/news/detail-847481.html
到了这里,关于Django - 视图和模板的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!