第18天课程内容:
- 模板语言的常用标签
- 自定义过滤器与标签
- 模板语言之继承
- ORM的查询API
- 单表查询之双下划线
- 一对多的添加数据方法
mtv补充
修改pycharm连接db为mysql时遇到的问题
解决:
在项目的__init__.py文件中加
import pymysql
pymysql.install_as_MySQLdb()
post提交表单数据时,默认会提示403 forbidden,需要在form表单处添加{% csrf_token %},render方法会为它渲染一个随机字符串一并提交给服务端做验证,就可以解决了;也可以临时在settings里注释掉关于csrf的配置。(不推荐)
自定义标签和过滤器
django提供的标签与过滤器毕竟有限,更多的是需要自己去自定义标签和过滤器,以下是过程:
1、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.
2、在app中创建templatetags模块(模块名只能是templatetags)
3、创建任意 .py 文件,如:my_tags.py
from django import template
from django.utils.safestring import mark_safe
register = template.Library()
# 以上为固定格式
@register.filter #自定义过滤器
def multi(x,y):
return x*y
@register.simple_tag#自定义标签
def mult_tag(x,y,z):
return x**y**z
4、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py
{
%
load my_tags
%
}
5、使用simple_tag和filter(如何调用)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{#自定义过滤器:在通过render方法渲染页面时只支持接受2个参数#}
{% load Mytag %}
<h2>{{ n1|multi:2 }}</h2>
<hr>
{#自定义标签:可以接受多个参数,通过render方法渲染页面时也没问题#}
<h1>{% mult_tag 2 6 2%}</h1>
</body>
</html>注意:filter可以用在if等语句后,simple_tag不可以
{
%
if
num|filter_multi:
30
>
100
%
}
{{ num|filter_multi:
30
}}
{
%
endif
%
}
总结:
tempalte(模板层):
功能: 为了更有逻辑的将数据库中的数据渲染到模板中
模板语法
变量 {{ }}
深度查询: 句点符 .
过滤器: {{var|filter_name:参数}}
标签 {% url %}
{% for i in obj %} {% endfor %}
{% if %} {%endif%}
{% with %}
{% csrf_token%}
自定义过滤器与标签:
定义流程:
1、在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.
2、在app中创建templatetags模块(模块名只能是templatetags)
3、创建任意 .py 文件,如:my_tags.py:
from django import template
from django.utils.safestring import mark_safe
register = template.Library() # register的名字是固定的,不可改变
@register.filter # 定义过滤器
def multi(x,y):
return x*y
@register.simple_tag # 定义标签
def multi_tag(x,y,z):
return x*y*z
4、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py
{% load my_tags %}
5、使用simple_tag和filter(如何调用)
总结区别:
1、自定义filter只能接受两个参数
2、自定义simple_tag不能与if使用
继承:
创建base.html
{%block content%}{%endblock%}
模板继承 (extend)
Django模版引擎中最强大也是最复杂的部分就是模版继承了。模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。
通过从下面这个例子开始,可以容易的理解模版继承:
View Code这个模版,我们把它叫作
base.html
, 它定义了一个可以用于两列排版页面的简单HTML骨架。“子模版”的工作是用它们的内容填充空的blocks。在这个例子中,
block
标签定义了三个可以被子模版内容填充的block。block
告诉模版引擎: 子模版可能会覆盖掉模版中的这些位置。子模版可能看起来是这样的:
View Code
extends
标签是这里的关键。它告诉模版引擎,这个模版“继承”了另一个模版。当模版系统处理这个模版时,首先,它将定位父模版——在此例中,就是“base.html”。那时,模版引擎将注意到
View Codebase.html
中的三个block
标签,并用子模版中的内容来替换这些block。根据blog_entries
的值,输出可能看起来是这样的:请注意,子模版并没有定义
sidebar
block,所以系统使用了父模版中的值。父模版的{% block %}
标签中的内容总是被用作备选内容(fallback)。
这种方式使代码得到最大程度的复用,并且使得添加内容到共享的内容区域更加简单,例如,部分范围内的导航。
这里是使用继承的一些提示:
如果你在模版中使用
{% extends %}
标签,它必须是模版中的第一个标签。其他的任何情况下,模版继承都将无法工作。在base模版中设置越多的
{% block %}
标签越好。请记住,子模版不必定义全部父模版中的blocks,所以,你可以在大多数blocks中填充合理的默认内容,然后,只定义你需要的那一个。多一点钩子总比少一点好。如果你发现你自己在大量的模版中复制内容,那可能意味着你应该把内容移动到父模版中的一个
{% block %}
中。If you need to get the content of the block from the parent template, the
{{ block.super }}
variable will do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding it. Data inserted using{{ block.super }}
will not be automatically escaped (see the next section), since it was already escaped, if necessary, in the parent template.为了更好的可读性,你也可以给你的
{% endblock %}
标签一个 名字 。例如:{% block content %}
...
{% endblock content %}
在大型模版中,这个方法帮你清楚的看到哪一个
{% block %}
标签被关闭了。最后,请注意您并不能在一个模版中定义多个相同名字的
block
标签。这个限制的存在是因为block标签的作用是“双向”的。这个意思是,block标签不仅提供了一个坑去填,它还在 _父模版_中定义了填坑的内容。如果在一个模版中有两个名字一样的block
标签,模版的父模版将不知道使用哪个block的内容。
ORM的相关
ORM
映射关系:
表名 <-------> 类名
字段 <-------> 属性
表记录 <------->类实例对象创建表(建立模型)
实例:我们来假定下面这些概念,字段和关系
作者模型:一个作者有姓名和年龄。
作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息。作者详情模型和作者模型之间是一对一的关系(one-to-one)
出版商模型:出版商有名称,所在城市以及email。
书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)。
模型建立如下: