Django-02-视图和模板

首先,先简单理解下django的MTV模式。

  • M 代表模型(Model):负责业务对象和数据库的关系映射(ORM)。即:创建数据的字段和行为。
  • T 代表模板 (Template):负责如何把页面展示给用户(html)。
  • V 代表视图(View):负责业务逻辑,并在适当时候调用Model和Template(数据来源于哪个model及指定通过哪个template去展示)。

除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理。即:前端页面的url路径,与视图,与对应的名称(前端页面跳转时可指定名称去跳转)是通过url文件去关联的。

上一篇我们已经创建了模型,这里来看看View视图和Template模板。


View视图——通用视图ListView和DetailView

我们需要显示的视图如下:

  • 项目索引页——展示所有项目列表
  • 项目详情页——展示某个项目描述和该项目的进度列表

上一篇中已经创建过一个简单的index视图,现在我们会创建更复杂一点的视图。在这里使用django的两个通用视图: ListViewDetailView 。这两个视图分别抽象“显示一个对象列表”和“显示一个特定类型对象的详细信息页面”这两种概念。

代码如下:

from django.views import generic
from .models import Project, Schedule


class ProjectView(generic.ListView):
    model = Project
    template_name = 'projtrack/project.html'

    def get_queryset(self):
        return Project.objects.order_by('-cre_date')


class ScheduleView(generic.DetailView):
    model = Project
    template_name = 'projtrack/schedule.html'

注意:

  • 每个通用视图需要知道它将作用于哪个模型。 这由 model 属性提供。
  • ListView 使用一个叫做<app name>/<model name>_list.html 的默认模板;我们使用 template_name 来告诉 ListView 使用我们的 "projtrack/project.html" 模板。类似的,DetailView也是如此,使用"projtrack/schedule.html" 模板。
  • 对于ListView,定义了modelProject后,会自动生成context变量project_list,可以在html页面调用获取所有项目列表。也可以自定义一个context变量,比如“latest_project_list”,然后重写get_queryset方法,返回最近10条(自定义)的项目列表。
  • DetailView 期望从 URL 中捕获名为 "pk" 的主键值
  • 对于DetailView,定义了modelProject后,也会自动生成context变量project,可在html页面调用。

添加url对应视图的关系

projtrack/urls.py中添加path:

from django.urls import path
from . import views

app_name = 'projtrack'
urlpatterns = [
    path('', views.index, name='index'),
    path('project/', views.ProjectView.as_view(), name='project'),
    path('project/<int:pk>', views.ScheduleView.as_view(), name='schedule'),
]

注意:

  • 为了去除html页面中跳转页面时使用硬编码,可通过 name 参数为 URL 定义名字,这样就可以使用 {% url %} 标签。

比如点击某个项目名称,进入该项目的进度视图页面时使用的href:
<td><a href="/project/{{ project.id }}/">{{ project.project_name }}</a></td>
如果url.py中的path发生修改,则html页面的改动是挺麻烦的。用{% url %}标签后:
<td><a href="{% url 'schedule' project.id %}">{{ project.project_name }}</a></td>
即:寻找名为schedule的路径,路径中参数pk的值为project.id

  • 为 URL 名称添加命名空间,分辨不同应用中重名的 URL

当项目中存在多个应用时,在url中只通过name去找路径,有可能出现重名而定位不到或定位错误的问题。可通过添加命名空间解决。
projtrack/urls.py中添加app_name = 'projtrack',html页面中的href改为:
<td><a href="{% url 'projtrack:schedule' project.id %}">{{ project.project_name }}</a></td>
即:在projtrack中寻找名为schedule的路径。


Template模板

我们在View中指定了projtrack/project.html和projtrack/schedule.html作为前端页面去展示。在url.py中定义了视图对应的路径和路径名称。现在,在projtrack/中创建这两个页面并添加如下代码。

注意:这里project.html和schedule.html都是{% extends "projtrack/index.html %}"。也就是作为index.html页面的扩展,把一些公共的元素放在index页面,比如导航栏,用户显示,登录注册按钮等(这部分详细写在下一篇)。这里先简化index.html。

# projtrack/index.html

<!DOCTYPE html>
<html lang="zh-cn">
<title>Project Tracking System</title>
<head>
    <meta charset="utf-8">
</head>
<body>
    {% block body %}{% endblock %}
</body>
</html>
# projtrack/project.html

{% extends "projtrack/index.html" %}
{% block body %}
<div class="table-responsive">
<h2 class="sub-header">项目</h2>
<table class="table table-hover">
    <thead>
    <tr><th>#</th><th>项目</th><th>描述</th><th>创建时间</th><th>状态</th></tr>
    </thead>
{% if project_list %}
    {% for project in project_list %}
    <tr>
        <td>{{ forloop.counter }}</td>
        <td><a href="{% url 'projtrack:schedule' project.id %}">{{ project.project_name }}</a></td>
        <td>{{project.description}}</td>
        <td>{{project.cre_date}}</td>
        <td>{{project.project_status}}</td>
    </tr>
    {% endfor %}
{% else %}
    <tr>No projects are available.</tr>
{% endif %}
</table>
</div>
{% endif %}
{% endblock %}
# projtrack/schedule.html

{% extends "projtrack/index.html" %}
{% block body %}
<div class="table-responsive">
    <h2>项目:{{ project.project_name }}</h2>
    <h4>进度列表</h4>
<table class="table table-hover">
    <thead>
    <tr><th>#</th><th>阶段</th><th>进度名称</th><th>状态</th><th>文件</th><th>备注</th><th>修改时间</th><th>修改人</th></tr>
    </thead>
    {% for schedule in project.schedule_set.all %}
    <tr>
        <td>{{ forloop.counter }}</td>
        <td>{{ schedule.stage }}</td>
        <td>{{ schedule.schedule_text }}</td>
        <td>{{ schedule.status }}</td>
        <td>{{ schedule.photo }}</td>
        <td>{{ schedule.notes }}</td>
        <td>{{ schedule.modify_date }}</td>
        <td>{{ schedule.edit_by }}</td>
    </tr>>
{% endfor %}
</table>
</div>
{% endif %}
{% endblock %}

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

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,635评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,628评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,971评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,986评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,006评论 6 394
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,784评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,475评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,364评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,860评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,008评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,152评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,829评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,490评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,035评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,428评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,127评论 2 356

推荐阅读更多精彩内容