WEB后端服务第14天-Django第四天
一、 模型关系的深入应用
1.1 多对多的应用
需求: 用户收藏商品, 需要建立第三方表,完成用户收藏多个商品, 或一个商品被多位用户收藏。
在FruitEntity模型类中,增加users属性,内容如下:
# 默认情况下,反向引用的名称是当前类的名称(小写)_set
# 可以通过related_name 来指定
# db_table='t_collect' 使用第三张表建立fruit和user的多对多关系
users = models.ManyToManyField(UserEntity,
db_table='t_collect',
related_name='fruits',
verbose_name='收藏用户列表')
当迁移完成后,模拟用户收藏商品:
u1 = UserEntity.objects.get(pk=1)
u1.fruits.add(FruitEntity.objects.get(pk=1))
u1.fruits.add(FruitEntity.objects.get(pk=2))
u2 = UserEntity.objects.get(pk=2)
u2.fruits.add(FruitEntity.objects.get(pk=2))
查询某一件商品,被哪些用户收藏
fruit1 = FruitEntity.objects.get(pk=2)
fruit1.users.all()
用户取消收藏商品
u1.fruits.remove(FruitEntity.objects.get(pk=1))
练习任务: 增加标签模型类TagEntity(id, name, order_num)并且和商品建立多对多的关系
问题: 模型类自关联
二、模板语法
2.1 MTV设计中TV的关系
- V 视图理函数可以渲染(使用)多个模板
- 一个模板 T 可被任意的V 视图函数使用
2.2 模板的加载过程
模板加载对象: django.template.loader
- 加载
template = loader.get_template('index.html')
- 渲染
html = template.render(context) # context是一个dict类型对象
- 加载+渲染
html = loader.render_to_string("index.html", context)
2.3 模板中使用 “.” 点语法
使用 “.” 访问变量Variable的属性, 系统尝试以下顺序查询:
- 字典
- 属性或方法
- 列表的数值索引
<h3>{{ msg }}</h3>
<p style="color: green">
第三个用户名: {{ users.2.name }}
</p>
<p style="color: red;">
请客的人: {{ error_index }}
</p>
<p style="color: white;background-color:blue;">
<span>VIP:</span>
<span>{{ vip.name.upper }}-{{ vip.money }}</span>
</p>
<ul>
{% for key, value in vip.items %}
<li>{{ key }} = {{ value }}</li>
{% endfor %}
</ul>
<ul>
{% for user in users %}
<li>{{ user.id }} {{ user.name }}</li>
{% if forloop.counter0 == error_index %}
<p style="color: red;">
请客的人: {{ user.name }}
</p>
{% endif %}
{% endfor %}
</ul>
users = UserEntity.objects.all()
msg = '最优秀的学员'
error_index = random.randint(0, users.count()-1)
vip = {
'name': 'disen',
'money': 20000
}
# # 加载模板
# template = loader.get_template('user/list.html')
#
# # 渲染模板
# html = template.render(context={
# 'msg': msg,
# 'users': users
# })
html = loader.render_to_string('user/list.html',
locals())
return HttpResponse(html,
status=200) # 增加响应头??
中午默写:
现有采购记录表Stock和商品表Goods,画出或写出它们之间的关系及模型类
2.4 表达式标签
- {% if 条件 %} {% endif %}
- 条件表达式支持关系运算符
or
and
not
in
- == 、 !=、 > 、< 、>=、<=
- 条件表达式支持关系运算符
- {% ifeqaul 值1 值2 %} {% endifequal %}
- {% ifnoteqaul 值1 值2 %} {% endifnotequal %}
- {% for 变量 in 可迭代对象 %} {% endfor %}
- {% empty %} 当可迭代对象为空(非None), 显示empty标签下面的内容
- {% cycle 值1 值2 值3 值4 %}
- {{ forloop.counter }} 循环记数器, 从1开始
- 注释: 渲染模板之后不会存在的
- {# 单行注释 #}
- {% comment %} 多行注释的文本 {% endcomment %}
- escape 安全标签
- {% autoescape on|off %} 开启escape时, 会将变量的 大于号、小于号、单引号、双引号及&等转成escape的表示,如大于号为 >
- {{ info|escape }} escape也可以换成safe 表示不转换escape
2.5 模板的过滤器
-
数值运算
- |add:5
- |add:-5
- |divisibleby:2
- {% widthratio 变量 分母 分子 %}
-
字符串
-
格式化
-
日期格式化
now|date:“Y-m-d H:i:s”
-
文件大小格式化
file_size|filesizeformat
-
小数值格式化
v|floatformat:n 默认n 是1位小数
-
-
列表
-
HTML转义
{{ html|safe }} 不转义
{{ html|escape }} 转义, 显示html源码标签
-
默认值
2.6 自定义过滤器
在app的__init__.py脚本编写
from django.template.defaultfilters import register
import os
@register.filter('ellipse')
def ellipse(value):
return os.path.split(value)[-1]
2.7 扩展: os.stat()获取文件大小
file_dir = os.path.join(settings.BASE_DIR, 'mainapp/')
files = {file_name: os.stat(file_dir+file_name)
for file_name in os.listdir(file_dir)
if os.path.isfile(file_dir+file_name)}