Эта статья участвует в "Месяце тем Python", подробнее см.Ссылка на мероприятие
Поиск общедоступных номеров WeChat [Программа Юань Сяочжуан], Ленивый человек не может наслаждаться отдыхом.~
предисловие
Данные, сгенерированные в проекте, обычно изменяются, поэтому данные, отображаемые пользователю на странице внешнего интерфейса в проекте с полным стеком, также должны динамически генерироваться серверной частью, поэтому как данные, сгенерированные серверной частью, передаваемые на фронтенд и как фронтенд их получает Данные, отправляемые бэкендом и рендеринг, являются частью темы этой статьи. Вышеупомянутые три проблемы могут быть решены с помощью языка шаблонов Django, давайте посмотрим~
Tips
Front-end получает данные back-end и обрабатывает их, то есть существует два типа синтаксиса шаблона:{{}}和{% %}
, значение синтаксиса шаблона django имеет фиксированный формат и может использоваться только.
значение либо.索引
Вы также можете заказать.key
:
{{}} # 变量相关,用在接收后端传递过来的数据、过滤器、自定义过滤器
{% %} # 逻辑相关,用在标签(if判断 for循环)、自定义标签simple_tag、inclusion_tag、模版继承extend和导入include
<p>{{ d.key }}</p> # 字典使用点key方式
<p>{{ my_str.0 }}</p> # 字符串使用点索引的方式
<p>{{ l.0 }}</p> # 列表使用点索引的方式
<p>{{ obj.get_class }}</p> # 对象点属性或方法的方式
Как передать внутренние данные во внешний интерфейс
Прежде всего, вам нужно знать, как серверная часть передает данные во внешний интерфейс или какие типы данных может передавать во внешний интерфейс серверная часть django? Когда переменная передается по значению, она поддерживает как базовые типы данных Python, так и функции, классы и объекты Python.
базовый тип данных
Основные типы данных в Python передаются во внешний интерфейс, который может быть обработан.str, int, float, bool, set, dict, list, tuple
В проекте django способ отправки данных из бэкэнда на HTML-страницу очень прост.Вы можете вернуть данные, требуемые фронтендом, при возврате страницы в функции просмотра.Для этого есть два способа, и боссы может свободно выбирать:
словарь по значению
Передавая значения на фронтенд таким образом, на фронтенд страницу передаются только данные, требуемые фронтенду, недостаток в том, что это слишком хлопотно.
# views.py
def index(request):
my_str = 'string'
my_int = 11
my_list = [1, 2, 3]
my_tup = (1, 2, 3)
my_dic = {'name': 'python', 'age': 18}
my_set = {1, 3, 4}
my_bool = True
my_float = 11.11
return_dic = {
'str': my_str,
'int': my_int,
'list': my_list,
'dict': my_dic,
'tuple': my_tup,
'set': my_set,
'bool': my_bool,
'float': my_float,
}
return render(request, 'render_html.html', return_dic)
# render_html.html
<body>
{{ str }}
{{ int }}
{{ list }}
{{ dict }}
{{ tuple }}
{{ set }}
{{ bool }}
{{ float }}
</body>
locals()
Метод locals() может передавать все переменные из бэкенд-функции просмотра на фронтенд-страницу, преимущество в том, что это удобно, а недостаток в том, что некоторые данные могут не понадобиться фронтенду. Рекомендуется использовать этот метод, который очень удобен.Используйте этот метод для получения значения из бэкэнда и непосредственного получения значения через исходное имя переменной.
# views.py
def index(request):
my_str = 'string'
my_int = 11
my_list = [1, 2, 3]
my_tup = (1, 2, 3)
my_dic = {'name': 'python', 'age': 18}
my_set = {1, 3, 4}
my_bool = True
my_float = 11.11
return render(request, 'render_html.html', locals())
# render_html.html
<body>
{{ my_str }}
{{ my_int }}
{{ my_list }}
{{ my_tup }}
{{ my_dic }}
{{ my_set }}
{{ my_bool }}
{{ my_float }}
</body>
объект по значению
Синтаксис шаблона также поддерживает передачу функций, классов и объектов из серверной части во внешнюю;
Если имя функции передано, внешний интерфейс автоматически вызовет соответствующую функцию внутреннего интерфейса с круглыми скобками и получит возвращаемое значение функции, но синтаксис шаблона не поддерживает передачу параметров в функцию;
Если имя класса передано, клиентская часть непосредственно создаст экземпляр типа, соответствующего серверной части, в качестве объекта и распечатает объект на странице интерфейса.__str__
метод, вернуть возвращаемое значение метода;
Если переданный объект уже создан, если объект__call__
Может ли метод, то есть объект, вызываться напрямую через круглые скобки, он будет выполняться первым__call__
Возвращаемое значение внутри, если такого метода нет, то вывести объект напрямую.
# views.py
from django.shortcuts import render
# Create your views here.
def index(request):
def func():
print('我是func')
return 'func'
class Class():
def get_self(self):
return 'self'
@staticmethod
def static():
return 'static'
@classmethod
def class_method(cls):
return cls
# 打印类/对象是自动触发,代替对象的内存地址
def __str__(self):
return '我是谁?'
obj = Class()
return render(request,'data.html',locals())
# data.html
<p>传递函数名,就会将后端的函数自动加括号调用,得到该函数的返回值,但是模板语法不支持给函数传参数</p>
<p>传类名的时候也会自动加括号调用,即实例化</p>
<p>模版语法内部能够自动判断出当前的变量名是否可以加括号调用,如果可以就会自动执行,针对的是函数名和类名</p>
{{ func }}
<p>{{ Class }}</p>
<p>{{ obj }}</p>
<p>{{ obj.get_self }}</p>
<p>{{ obj.static }}</p>
<p>{{ obj.class_method}}</p>
фильтры фильтры
В языке шаблонов Django вы можете изменить отображение переменных с помощью фильтров.Фильтры аналогичны встроенным методам синтаксиса шаблона, аналогичны встроенным методам внутренних типов данных.Основной синтаксис:{{数据|过滤器:参数}}
, где параметры необязательны, два параметра стоят до и после вертикальной черты |, но фильтр может иметь не более двух параметров, фильтр поддерживает цепочку операций, то есть выход одного фильтра может использоваться как вход другого фильтра, в django более 60 встроенных фильтров, вот некоторые часто используемые фильтры.
<!--常用过滤器-->
<p>统计长度{{ my_str|length }}</p>
<p>默认值,如果布尔值是True,默认值就是True,否则展示冒号后面的值{{ my_bool|default:'啥也不是' }}</p>
<p>文件大小:{{ file_size|filesizeformat }}</p>
<p>日期格式化:{{ current_time|date:'Y-m-d H:i:s' }}</p>
<p>切片操作,支持步长,顾头不顾尾{{ my_list|slice:'0:2:1' }}</p>
<p>摘要操作包含三个点(比如掘金文章的摘要){{ info|truncatechars:9 }}</p>
<p>切取单词,不包含三个点,只会按照空格切分单词{{ egn|truncatewords:'9' }}</p>
<p>移除特定的字符{{ msg|cut:' ' }}</p>
<p>拼接操作{{ my_str|join:'@' }}</p>
<p>加法运算(拼接操作){{ my_int|add:12 }}</p>
<p>加法运算(拼接操作){{ my_str|add:'12' }}</p>
Кроме того, при написании проекта с полным стеком код внешнего интерфейса не обязательно должен быть написан на странице внешнего интерфейса, но также может быть написан на внутреннем интерфейсе, а затем передан во внешний интерфейс.safe
Фильтр, значение фильтра состоит в том, чтобы сообщить HTML-документу, что теги, переданные из серверной части, безопасны и могут быть отображены.
<!--后端代码-->
def index(request):
h = '<h1>我是html标签</h1>'
return render(request, 'render_html.html', locals())
<!-- - 前端转义,过滤器的意思是告诉浏览器后端写的标签是安全的,可以进行渲染-->
{{h|safe}}
В то же время бэкэнд также может напрямую преобразовать строку с меткой в код внешнего интерфейса, а затем внешний интерфейс можно использовать напрямую через синтаксис шаблона.
<!--后端代码-->
from django.utils.safestring import mark_safe
def index(request):
s = '<h1>后端转义</h1>'
res = mark_safe(s)
return(request, 'render_html.html', locals())
<!--前端代码-->
{{res}}
Этикетка
Этот тег не является другим тегом, тег здесь относится не к тегу в документе HTML, а куча логики в синтаксисе шаблона, эту логику можно использовать для обработки данных, передаваемых от серверной части к интерфейсу.
Страница интерфейса для цикла
Когда интерфейсная страница использует язык шаблона для выполнения цикла for с данными, есть два варианта использования: один — напрямую зацикливать и выводить каждый элемент в объекте цикла for, таком как python, а другой — передаватьforloop
Получить информацию о каждом элементе. Синтаксис шаблона для цикла for следующий:
{% for i in variable %}
variable非空时执行的代码
{% empty %}
variable为空时执行的代码
{% endfor %}
Например, следующий код:
# views.py
from django.shortcuts import render
# Create your views here.
def index(request):
my_str = 'string'
my_dic = {'name': 'python', 'age': 18}
my_list = []
return render(request, 'render_html.html', locals())
<!--render_html.html-->
<body>
<p>i就是每次循环得到的元素值,而每次循环得到的forloop是每个元素的详细信息</p>
{% for i in my_str %}
<p>{{ i }}, {{ forloop }}</p>
{% endfor %}
{% for i in my_list %}
<p>我不会被执行</p>
{% empty %}
<p>因为my_list是空的,所以我会被执行</p>
{% endfor %}
<!--for循环处理字典的方法与python后端非常类似-->
{% for foo in my_dic.keys %}
<p>{{ foo }}</p>
{% endfor %}
{% for foo in my_dic.values %}
<p>{{ foo }}</p>
{% endfor %}
{% for foo in my_dic.items %}
<p>{{ foo }}</p>
{% endfor %}
</body>
----------------------------------页面结果如下----------------------------------
s, {'parentloop': {}, 'counter0': 0, 'counter': 1, 'revcounter': 6, 'revcounter0': 5, 'first': True, 'last': False}
t, {'parentloop': {}, 'counter0': 1, 'counter': 2, 'revcounter': 5, 'revcounter0': 4, 'first': False, 'last': False}
r, {'parentloop': {}, 'counter0': 2, 'counter': 3, 'revcounter': 4, 'revcounter0': 3, 'first': False, 'last': False}
i, {'parentloop': {}, 'counter0': 3, 'counter': 4, 'revcounter': 3, 'revcounter0': 2, 'first': False, 'last': False}
n, {'parentloop': {}, 'counter0': 4, 'counter': 5, 'revcounter': 2, 'revcounter0': 1, 'first': False, 'last': False}
g, {'parentloop': {}, 'counter0': 5, 'counter': 6, 'revcounter': 1, 'revcounter0': 0, 'first': False, 'last': True}
......
----------------------------------结果分析-------------------------------------------
每行的第一个元素就是for循环后得到的i值;
每行后面的字典就是forloop,每个元素的详细信息,代表意思分别如下:
counter0:从零开始计算索引,当前元素的索引值
counter:从1开始计算索引,当前元素的索引值
revcounter:从1开始计算索引,将索引值反过来后当前元素的索引值
revcounter0:从0开始计算索引,将索引值反过来后当前元素的索引值
first:表示当前元素是否是第一个元素
last:表示当前元素是否是最后一个元素
если суждение
Суждение if в синтаксисе шаблона похоже на суждение if в python и поддерживаетand 、or、==、>、<、!=、<=、>=、in、not in、is、is not
судить.
<body>
{% if my_bool %}
my_bool
{% elif False %}
哈哈
{% else %}
上面都不成立才执行到我
{% endif %}
</body>
с псевдонимами
В синтаксисе with можно быстро использовать данные, полученные очень сложным способом получения данных через псевдоним после as, то есть псевдоним сложных переменных, таких как:
from django.shortcuts import render
# Create your views here.
def index(request):
my_dic = {
'name': 'python',
'age': 18,
'hobby': ['study', 'play']
}
return render(request, 'render_html.html', locals())
<body>
{% with my_dic.hobby.0 as myhobby %}
with语法{{ myhobby }}
直接获取{{ my_dic.hobby.0 }}
{% endwith %}
</body>
Пользовательские фильтры, теги и тег включения
Пользовательские фильтры, пользовательские теги и настраиваемые теги включения имеют три идентичных шага в процессе настройки, а именно:
① Создайте имя под приложениемдолженПапка под названием templatetags;
②Создать в этой папкелюбое имяpy-файл;
③В файле pyдолженСначала напишите следующие две строки кода;
from django import template register = template.Library()
пользовательский фильтр
Пользовательский фильтр должен определить фильтр в файле py, созданном в каталоге templatetags.Функция аналогична встроенному фильтру.Он получает и обрабатывает данные, передаваемые функцией просмотра.Если встроенный фильтр не может удовлетворить требования, вы можете использовать пользовательский фильтр filter. Следует отметить, что пользовательский фильтр может принимать не более двух параметров, например определение фильтра, вычисляющего сумму двух элементов:
# templatetags/my_filter.py
from django import template
register = template.Library()
@register.filter(name='sum') # name=自定义过滤器的名字
# 过滤器的功能
def my_sum(v1, v2): # 过滤器接收两个参数
return v1 + v2
Чтобы использовать настраиваемый фильтр в HTML-документе, необходимо сначала загрузить его следующим образом:
<body>
{% load sum %} <!--先加载自定义过滤器-->
{{ my_int }}
{{ my_int|my_sum:666 }}
</body>
пользовательский ярлык
Также необходимо создать py-файл в каталоге templatetags.Вы можете использовать тот же py-файл, что и пользовательский фильтр, но рекомендуется отделить его для удобства управления.Внешняя страница вызывает пользовательский тег для обработки данных , Если существующие теги в синтаксисе шаблона не соответствуют требованиям для логической обработки данных, можно настроить теги для обработки данных. Например, следующие пользовательские теги:
# templatetags/my_tag.py
from django import template
register = template.Library()
# 自定义标签,参数可以有多个
@register.simple_tag(name='my_tag') # name=自定义标签的名字
def index(a,b,c):
return f'{a}{b}{c}'
Чтобы использовать пользовательский тег в документе HTML, сначала необходимо загрузить файл, в котором находится пользовательский тег.Метод использования следующий:
<body>
{% load my_tag %}
<!--自定义标签使用语法:{% 标签名 参数1 参数2 参数3....%},标签多个参数彼此之间空格隔开-->
{% my_tag 'a' 'b' 'c' 'd' %}
</body>
пользовательский include_tag
Принцип пользовательского include_tag немного сложнее, конкретный принцип заключается в следующем:
Во-первых, создайте py-файл в каталоге templatetags и определите метод.При определении метода укажите, в какой HTML-документ следует передать данные, возвращаемые методом, например a.html;
В документе HTML, таком как b.html, вызывается этот метод, и при вызове этому методу может быть передано значение;
Пользовательский метод будет получать данные из b.html и возвращать результат на HTML-страницу a.html, указанную при определении метода;
Наконец, поместите обработанную страницу a.html на место страницы b.html, которая вызывает пользовательский метод.
Хм.... Я тоже думаю, что это немного запутанно, давайте нарисуем картинку и объясним~
** Когда страница в определенном месте HTML-страницы должна передавать параметры для динамического рендеринга, а частичную страницу необходимо использовать на нескольких страницах, можно рассмотреть возможность использования include_tag. ** Конкретное использование выглядит следующим образом:
# templatetags/my_inclusion_tag.py
from django import template
register = template.Library()
@register.inclusion_tag(filename='local.html', name='my_inclusion') # 指定将返回的数据传递给local.html文件,如果不指定name在页面中调用inclusion_tag时写函数名即可
def test(n):
data = ['第{}项'.format(i) for i in range(n)]
return locals()
<!--local.html,inclusion_tag指定的页面-->
{% for i in data %}
<li>{{ i }}</li>
{% endfor %}
<!--render_html.html,调用inclusion_tag的页面-->
<body>
{% load my_inclusion_tag %} <!--首先需要加载inclusion_tag-->
{% my_inclusion 5 %} <!--调用inclusion_tag,语法为{% 自定义inclusion_tag的函数名 参数%}-->
</body>
Наследование шаблона страницы
Я не знаю, обнаружили ли какие-либо внимательные друзья, что на самом деле изменения страниц многих веб-сайтов меняются не все, а только частично. Чтобы добиться эффекта изменения только части страницы, это может быть достигнуто через наследование шаблонов, например панель навигации Nuggets. Независимо от того, к какой странице осуществляется доступ, панель навигации не изменится. Этого эффекта можно добиться с помощью наследования шаблонов страниц. Реализация наследования шаблонов может быть разделена на следующие этапы:
Первым шагом является выбор страницы шаблона в качестве страницы, наследуемой другими страницами.
Вторым шагом является очистка нужного содержимого в документах HTML других страниц, которые наследуют страницу шаблона, потому что эта страница больше не целая страница, а частичная страница, называемая подстраницей, и необходимо написать следующее по коду подстраницы;
{% extends '模板页面的文件名' %}
<!--这行代码的意思就是继承了模板页面上的所有的内容-->
Третий шаг — разграничить область, которую можно изменить на странице шаблона.Метод разграничения следующий:
<!--模板页面-->
{% block content %} // content是可以被修改部分的名字,可以是任意的
模板页面上可以被修改的部分
{% endblock%}
Четвертый шаг — объявить на подстранице, что вы хотите изменить содержимое страницы шаблона:
{% block content %} // content是可以被修改部分的名字,可以是任意的
子页面独有的内容
{% endblock%}
Кроме того, необходимо добавить, что в нормальных условиях страница шаблона должна иметь как минимум три области, которые можно модифицировать, а именно:
- Область css размещается в теге head.
- HTML-область
- область js размещается внизу страницы
Поэтому на странице шаблона должно быть три места, которые можно рисовать и изменять, чтобы каждая подстраница могла иметь свой уникальный код js и css, но следует отметить, что в целом область, ограниченная на странице шаблона больше, тем выше масштабируемость шаблона, но областей не слишком много:
<!--模板页面-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
{% block css %}
<style></style>
{% endblock %}
</head>
<body>
<p>我是不能修改的部分</p>
{% block content %}
我是可以修改的地方
{% endblock %}
</body>
{% block js %}
<script></script>
{% endblock %}
</html>
Импорт шаблона
Помимо наследования, шаблоны также могут импортировать определенную страницу (частичную страницу) в качестве модуля, причем эту страницу необходимо импортировать напрямую, как показано в следующем коде:
语法格式:{% include '被导入页面的名字 '%}
{% include 'mu.html' %}
Эпилог
Статья была впервые опубликована в публичном аккаунте WeChat.Ченг Юань Сяочжуан, синхронизировано сНаггетс.
Кодировать слова непросто, объясните, пожалуйста, источник перепечатки, а маленькие друзья, которые проходят мимо, протягивают свои милые пальчики и ставят лайк перед уходом (╹▽╹)