当前位置: 首页 > news >正文

Django入门-3.公共视图

公共视图

视图 是具有 一类具有相同功能和模板的网页的集合,网页和其他内容都是从视图派生而来。每个视图是一个python函数。

一般情况下URL形式: /newsarchive/<year>/<month>/

为了将 URL 和视图关联起来,Django 使用了 ‘URLconfs’ 来配置。URLconf 将 URL 模式映射到视图。

其实就是类似于web项目里面的Controller里面的一个方法【一个GetMapping或者RequestMapping类似】

添加视图

在 pulls/views.py 中添加方法

from django.shortcuts import render
from django.http import HttpResponsedef index(request):return HttpResponse("Hello, world. You're at the polls index.")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)

在 pulls/urls.py 中添加路径映射, 类似于 java web 中的

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"),]

全局的 mysite/urls.py 已经 引入了 pulls/urls.py 就不需要变更了

在浏览器输入
/polls/34 会根据path进行匹配到detail方法中

每个视图都必须要做的是返回一个HttpResponse对象或者抛出异常比如 Http404

举例从 index() 方法改下

from polls.models import Questiondef index(request):latest_question_list = Question.objects.order_by('-pub_date')[:5]    # 查询数据库 根据 pub_date 逆序 取5条数据output = ", ".join([q.question_text for q in latest_question_list])return HttpResponse(output)

编辑页面
在polls 目录里创建一个 templates 目录。

项目的 TEMPLATES 配置项描述了 Django 如何载入和渲染模板。默认的设置文件设置了 DjangoTemplates 后端,并将 APP_DIRS 设置成了 True。这一选项将会让 DjangoTemplates 在每个 INSTALLED_APPS 文件夹中寻找 “templates” 子目录。这就是为什么尽管我们没有像在第二部分中那样修改 DIRS 设置,Django 也能正确找到 polls 的模板位置的原因。

在这里插入图片描述

在刚刚创建的 templates 目录里,再创建一个目录 polls,然后在其中新建一个文件 index.html 。换句话说,你的模板文件的路径应该是 polls/templates/polls/index.html 。因为app_directories 模板加载器是通过上述描述的方法运行的,所以 Django 可以引用到 polls/index.html 这一模板了

polls/templates/polls/index.html文件内容

<!doctype html>
<html lang="en-US"><head><meta charset="utf-8" /><title>question list</title></head><body>{% 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/views.py 里的 index 视图来使用我们创建的模板

from django.template import loaderfrom polls.models import Questiondef index(request):latest_question_list = Question.objects.order_by('-pub_date')[:5]  # 查询数据库 根据 pub_date 逆序 取5条数据template = loader.get_template("polls/index.html")        # 获取对应的模版context = {"latest_question_list": latest_question_list}  # 参数绑定,传递上下文,字典return HttpResponse(template.render(context, request))    # 返回对象

地址栏访问 http://127.0.0.1:8000/polls/

在这里插入图片描述

快捷函数: render()

上面的流程配置还是有很多重复的代码,如果编写多个方法的时候

from django.shortcuts import renderfrom .models import Questiondef 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)

抛出 错误

可以用来处理一些异常数据

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})

如果指定问题 ID 所对应的问题不存在,这个视图就会抛出一个 Http404 异常。

同时我们对应的 页面

polls/templates/polls/detail.html文件内容

<!doctype html>
<html lang="en-US"><head><meta charset="utf-8" /><title>question list</title></head><body>{{ question }}</body>
</html>

在这里插入图片描述
在这里插入图片描述

快捷函数: get_object_or_404()

尝试用 get() 函数获取一个对象,如果不存在就抛出 Http404 错误也是一个普遍的流程。Django 也提供了一个快捷函数,下面是修改后的详情 detail() 视图代码:

from django.shortcuts import get_object_or_404, renderfrom .models import Questiondef detail(request, question_id):question = get_object_or_404(Question, pk=question_id)return render(request, "polls/detail.html", {"question": question})

也有 get_list_or_404() 函数,工作原理和 get_object_or_404() 一样,除了 get() 函数被换成了 filter() 函数。如果列表为空的话会抛出 Http404 异常。

使用模版系统

polls/detail.html 模板里正式的代码

<!doctype html>
<html lang="en-US">
<head><meta charset="utf-8" /><title>question list</title>
</head>
<body>
<h1>{{ question.question_text }}</h1>
<ul>{% for choice in question.choice_set.all %}<li>{{ choice.choice_text }}</li>{% endfor %}
</ul>
</body>
</html>

模板系统统一使用点符号来访问变量的属性。在示例 {{ question.question_text }} 中,首先 Django 尝试对 question 对象使用字典查找(也就是使用 obj.get(str) 操作),如果失败了就尝试属性查找(也就是 obj.str 操作),结果是成功了。如果这一操作也失败的话,将会尝试列表查找(也就是 obj[int] 操作)。

{% for %} 循环中发生的函数调用:question.choice_set.all 被解释为 Python 代码 question.choice_set.all() ,将会返回一个可迭代的 Choice 对象,这一对象可以在 {% for %} 标签内部使用。

去除模板中的硬编码 URL

我们在 polls/index.html 里编写投票链接时,链接是硬编码的:

<li><a href="/polls/{{ question.id }}/">{{ question.question_text }}</a></li>

这种硬编码、强耦合的方法的问题在于,在具有大量模板的项目中更改 URL 变得具有挑战性。然而,由于你在 polls.urls 模块中的 path() 函数中定义了 name 参数,你可以通过使用 {% url %} 模板标签来消除对 url 配置中定义的特定 URL 路径的依赖:

<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

这个标签的工作方式是在 polls.urls 模块的 URL 定义中寻具有指定名字的条目。你可以回忆一下,具有名字 ‘detail’ 的 URL 是在如下语句中定义的:

path("<int:question_id>/", views.detail, name="detail"),

如果你想改变投票详情视图的 URL,比如想改成 polls/specifics/12/ ,你不用在模板里修改任何东西(包括其它模板),只要在 polls/urls.py 里稍微修改一下就行:

path("specifics/<int:question_id>/", views.detail, name="detail"),

为 URL 名称添加命名空间

教程项目只有一个应用,polls 。在一个真实的 Django 项目中,可能会有五个,十个,二十个,甚至更多应用。Django 如何分辨重名的 URL 呢?举个例子,polls 应用有 detail 视图,可能另一个博客应用也有同名的视图。Django 如何知道 {% url %} 标签到底对应哪一个应用的 URL 呢?

答案是:在根 URLconf 中添加命名空间。在 polls/urls.py 文件中稍作修改,加上 app_name 设置命名空间:

from django.urls import pathfrom . import viewsapp_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"),
]

现在,编辑 polls/index.html 文件,从:

<li><a href="{% url 'detail' question.id %}">{{ question.question_text }}</a></li>

修改为指向具有命名空间的详细视图:

<li><a href="{% url 'polls:detail' question.id %}">{{ question.question_text }}</a></li>
http://www.dtcms.com/a/394771.html

相关文章:

  • 【 设计模式 | 结构型模式 代理模式 】
  • 小杰机器学习高级(five)——分类算法的评估标准
  • IS-IS 中同时收到 L1 和 L2 的 LSP 时,是否优选 L1
  • 【开源】基于STM32的智能车尾灯
  • 电子电气架构 --- 软件开发与产品系统集成流程(下)
  • Ubuntu系统目录架构是怎么样的
  • 自动驾驶仿真之“场景交互”技术研究
  • 《AI管家还是数字化身?—— 一种面向未来的个人智能架构构想》
  • AI提升工业生产制造安全,基于YOLOv9全系列【yolov9/t/s/m/c/e】参数模型开发构建工业生产制造加工场景下工业设备泄漏智能化检测识别预警系统
  • 深度学习(十一):深度神经网络和前向传播
  • js立即执行函数的几种写法
  • RecyclerView里更新列表数是不想让header也刷新,怎么处理
  • C#/.NET/.NET Core技术前沿周刊 | 第 55 期(2025年9.15-9.21)
  • 减少实验烦恼,革新实验效率——PFA塑料容量瓶降低实验成本与风险
  • 留给石头科技的赛道不多了
  • 基于卷积神经网络的人车识别技术:从原理突破到场景重构的深度探索
  • 信用免押租赁服务:重构消费信任体系的全球增长引擎
  • Redis数据迁移实战:从自建到云托管(阿里云/腾讯云)的平滑过渡
  • 从梵高到赛博格:我用4K模型重构艺术史的未来可能性-Seedream 4.0 实测
  • Mysql DBA学习笔记(Redo Log/Undo Log)
  • 买卖T平台如何以分红+排队免单重构零售生态?
  • 2025 年前端工具全景解析:从框架到 AI,重构开发效率的 N 种可能
  • 重构ruoyi前后端分离版
  • AI + 制造:AI 如何重构制造业的质检与排产流程
  • 卡尔曼滤波
  • Django安全完全指南:构建坚不可摧的Web应用
  • Mysql DBA学习笔记(MVCC)
  • 【论文阅读】GR-1:释放大规模视频生成式预训练用于视觉机器人操控
  • 分布式光伏阴影轨迹模拟
  • 【Java.数据结构】初识集合框架