Django学习目录
Django的学习笔记
1、Django的出现
django为什么会出现:
- 在 Web 早期阶段,开发者手动编写每个页面。更新网站要编辑 HTML;重新设计要重新制作每一个网页,而且一次只能改一个网页。随着网站体量的增大,这种方式立马变得繁琐、浪费时间,最终变得不切实际。
django目标:
- 使用 Django 能在极短的时间内构建全面动态的网站。Django 的主旨是让你集中精力在有趣的工作上,减轻重复劳作的痛苦。为此,它为常用的 Web 开发模式提供了高层抽象,为常见的编程任务提供了捷径,还为解 决问题提供了清晰的约定
Django 的核心
1. 表现与逻辑分离
2. 避免重复
3. 与 HTML 解耦
4. XML 不好
5. 不要求具备设计能力
6. 透明处理空格
7. 不重造一门编程语言
8. 确保安全有保障
9. 可扩展
Django 是“为快节奏完美主义者而生的框架”。
2、Django的设计模式MTV
MVC设计模式
-
模型(M)是数据的表述。它不是真正的数据,而是数据的接口。使用模型从数据库中获取数据时, 无需知道底层数据库错综复杂的知识。模型通常还会为数据库提供一层抽象,这样同一个模型就能使 用不同的数据库。
-
视图(V)是你看到的界面。它是模型的表现层。在电脑中,视图是你在浏览器中看到的 Web 应用的页面,或者是桌面应用的 UI。视图还提供了收集用户输入的接口。
-
控制器(C)控制模型和视图之间的信息流动。它通过程序逻辑判断通过模型从数据库中获取什么信 息,以及把什么信息传给视图。它还通过视图从用户那里收集信息,并且实现业务逻辑:变更视图, 或者通过模型修改数据,或者二者兼具。
MTV设计模式
-
M 表示“模型”,即数据访问层。这一层包含所有与数据相关的功能:访问数据的方式、验证数据的方 式、数据的行为、数据之间的关系。
-
T 表示“模板”,即表现层。这一层包含表现相关的决策:在网页或其他文档类型中如何显示某个东 西。
-
V 表示“视图”,即业务逻辑层。这一层包含访问模型和选择合适模板的逻辑。你可以把视图看做模型 和模板之间的桥梁。
核心内容
3、URL 路由层
URL 配置以及 Django 背后的一个重要哲学:松耦合。
1、简单来说,松耦合是一 种软件开发方式,其价值在于让组件可以互换。如果两部分代码之间是松耦合的,那么改动其中一部分对另 一部分的影响很小,甚至没有影响。
在 Django Web 应用中,URL定义与所调用的视图函数之间 是松耦合的,即某个功能使用哪个URL与视图函数的实现本身放在两个地方。
-
静态的URL
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^hello/$', views.hello_world),] -
动态的URL
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^time/$', current_datetime),
url(r'^time/plus/(\d{1,2})/$', hours_ahead),]
Django 的核心哲学之一是,URL应该美观。
- / time/plus/3/这样的URL更加简洁明了,更加易于阅读,更加易于大声读出来......而且比使用查询字符串的版本美观得多。
- 美观的 URL 是高质量 Web 应用的一个特色。
- Django 的 URL 配置系统鼓励使用美观的 URL,而且为此提供了简易的方式。
有名分组
在Python 正则表达式中,命名正则表达式组的语法是(?P<name>pattern),其中name 是组的名称,pattern 是要匹配的模式.
urlpatterns = [
urlpatterns = [
re_path(r'^articles/2003/$', views.special_case_2003),
re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/$', views.article_detail),
],
注意
• 若想捕获 URL 中的值,把值放在括号里。
• 无需使用前导斜线,每个 URL 本身就有。例如,是 ^reviews,而非 ^/reviews。
• 每个正则表达式字符串前面的 'r' 是可选的,但是建议加上。它的作用是告诉 Python,那是“原始”字符串,里面的一切内容都不应该转义。
4、Django 模板
什么是模板
Django 模板是一些文本字符串,作用是把文档的表现与数据区分开。模板定义一些占位符和基本的逻辑(模板标签),规定如何显示文档。通常,模板用于生成 HTML,不过 Django 模板可以生成任何基于文本的格式。
<html>
<head>
<title>标题</title>
</head>
<body>
<h1>欢迎</h1>
<p>亲爱的 {{ person_name }},</p>
<p>谢谢你来到我们的 {{ company }}参加年会. 我们公司成立于{{
create_date|date:"Y-m-d" }}.</p>
<p>接下来我宣布一下今天的活动流程:</p>
<ul>
{% for item in item_list %}
<li>{{ item }}</li>{% endfor %}
</ul>
{% if ordered_win %}
<p>恭喜你获得了奖品.</p>
{% else %}
<p>
恭喜你获得了纪念品。
</p>
{% endif %}
<p>谢谢大家参加,<br />{{ company }}</p>
</body>
</html>
这个模板的大部分内容是 HTML,内含一些变量和模板标签。下面详细说明。
-
{{ person_name }}
意思是“把指定变量的值插入这里” -
{% if ordered_win %}) ,{% else %}
if 标签的作用是编写逻辑判断语句。 -
{% for item in item_list %})
for 标签的作用与 Python 中的 for 语句很像,用于迭代序列中的各个元素。 -
{{create_date|date: "Y-m-d" }}
我们把create_date变量传给 date 过滤器,并且为date过滤器指定 "Y-m-d" 参数。date 过滤器使用参数指定的格式格式化日期。过滤器使用管道符号(|)依附,类似于 Unix 管道。
模板语言
(DTL:Django Template Language)
创建模板,Template 类在 django.template 模块中,HTML文件都在此文件下创建。
1、模板标签
if 标签
{% if today_is_weekend %}
<p>Welcome to the weekend!</p>
{% else %}
<p>Get back to work.</p>
{% endif %}
if 标签还可以有一个或多个 {% elif %} 子句:
{% if %} 支持使用 and、or 或 not 测试多个变量,或者取反指定的变量
在同一个标签中可以同时使用 and 和 or,此时,and 的优先级比 or 高。
for标签
{% for %} 标签用于迭代序列中的各个元素。与 Python 的 for 语句一样,句法是 for X in Y,其中 Y 是要迭 代的序列,X 是单次循环中使用的变量。每次迭代时,模板系统会渲染 {% for %} 和 {% endfor %} 之间的内 容。
{% for key, value in data.items %}
{{ key }}: {{ value }}
{% endfor %}
for 标签支持一个可选的 {% empty %} 子句。
{% for athlete in athlete_list %}
<p>{{ athlete.name }}</p>
{% empty %}
<p>There are no athletes. Only computer programmers.</p>
{% endfor %}
- for循环下面有个名为 forloop 的模板变量。
- forloop.counter的值是一个整数,表示循环的次数。这个属性的值从1开始。
- forloop.counter 0与forloop.counter类似,不过是从零开始的。第一次循环时,其值为0。
- forloop.revcounter的值是一个整数,表示循环中剩余的元素数量。第一次循环时,for- loop.revcounter 的值是序列中要遍历的元素总数。最后一次循环时,forloop.revcounter 的值为 1。
- forloop.revcounter0与forloop.revcounter类似,不过索引是基于零的。第一次循环时,for- loop.revcounter0 的值是序列中元素数量减去一。最后一次循环时,forloop.revcounter0 的值为 0。
- forloop.first是个布尔值,第一次循环时为True。
- forloop.last是个布尔值,最后一次循环时为True。
注释
与 HTML 和 Python 一样,Django 模板语言支持注释。
注释使用 {# #} 标明:
2、过滤器
举例:
default
如果一个变量是false或者为空,使用给定的默认值。否则,使用变量的值。例如:
{{ value|default:"nothing" }}
length
返回值的长度。它对字符串和列表都起作用。例如:
{{ value|length }}
如果 value 是 ['a', 'b', 'c', 'd'],那么输出是 4。
date
value=datetime.datetime.now()
{{ value|date:"Y-m-d" }}
显示数据为:年 - 月 -日
3、模板继承 (extend)
Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。
通过从下面这个例子开始,可以容易的理解模版继承:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>{% block title %}My amazing site{%/span> endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
这个模版,我们把它叫作 base.html, 它定义了一个可以用于两列排版页面的简单HTML骨架。“子模版”的工作是用它们的内容填充空的blocks。
在这个例子中, block 标签定义了三个可以被子模版内容填充的block。 block 告诉模版引擎: 子模版可能会覆盖掉模版中的这些位置。
子模版可能看起来是这样的:
{% extends "base.html" %}
{% block title %}My amazing blog{% endblock %}
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
extends 标签是这里的关键。它告诉模版引擎,这个模版“继承”了另一个模版。当模版系统处理这个模版时,首先,它将定位父模版——在此例中,就是“base.html”。
那时,模版引擎将注意到 base.html 中的三个 block 标签,并用子模版中的内容来替换这些block。根据 blog_entries 的值,输出可能看起来是这样的:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>My amazing blog</title>
</head>
<body>
<div id="sidebar">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
</div>
<div id="content">
<h2>Entry one</h2>
<p>This is my first entry.</p>
<h2>Entry two</h2>
<p>This is my second entry.</p>
</div>
</body>
</html>
请注意,子模版并没有定义 sidebar block,所以系统使用了父模版中的值。父模版的 {% block %} 标签中的内容总是被用作备选内容(fallback)。
这种方式使代码得到最大程度的复用,并且使得添加内容到共享的内容区域更加简单,例如,部分范围内的导航。
这里是使用继承的一些提示:
-
如果你在模版中使用 {% extends %} 标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作。
-
在base模版中设置越多的 {% block %} 标签越好。请记住,子模版不必定义全部父模版中的blocks,所以,你可以在大多数blocks中填充合理的默认内容,然后,只定义你需要的那一个。多一点钩子总比少一点好。
-
如果你发现你自己在大量的模版中复制内容,那可能意味着你应该把内容移动到父模版中的一个 {% block %} 中。
-
为了更好的可读性,你也可以给你的{% endblock %} 标签一个 名字 。例如:
{% block content %}
... -
不能在一个模版中定义多个相同名字的 block 标签。