每天40分玩转Django:Django模板系统

server/2024/12/14 17:00:00/

Django模板系统

一、课程概述

学习项目具体内容预计用时
模板语法变量、标签、过滤器、注释90分钟
模板继承模板层级、块、包含60分钟
静态文件配置、管理、使用90分钟

在这里插入图片描述

二、模板基础配置

2.1 模板配置

python"># settings.py
TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [BASE_DIR / 'templates'],  # 模板目录'APP_DIRS': True,  # 是否在应用中查找模板'OPTIONS': {'context_processors': ['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages','blog.context_processors.categories',  # 自定义上下文处理器],},},
]

2.2 项目结构

myproject/├── manage.py├── myproject/│   └── settings.py├── templates/│   ├── base.html│   └── blog/│       ├── post_list.html│       ├── post_detail.html│       └── includes/│           ├── header.html│           ├── sidebar.html│           └── footer.html└── static/├── css/├── js/└── images/

三、模板语法

3.1 基本语法示例

<!-- templates/blog/post_list.html -->
{% extends 'base.html' %}
{% load static %}{% block title %}博客文章列表{% endblock %}{% block content %}<div class="posts">{# 这是单行注释 #}{% comment %}这是多行注释可以写很多行{% endcomment %}{# 变量输出 #}<h1>{{ page_title }}</h1>{# 条件判断 #}{% if posts %}{# 循环遍历 #}{% for post in posts %}<article class="post"><h2>{{ post.title }}</h2>{# 过滤器使用 #}<p>{{ post.body|truncatewords:30|linebreaks }}</p><p>作者:{{ post.author.username|default:"匿名" }}</p><p>发布时间:{{ post.publish|date:"Y-m-d H:i" }}</p></article>{% empty %}<p>暂无文章</p>{% endfor %}{% else %}<p>没有找到任何文章</p>{% endif %}</div>
{% endblock %}

3.2 常用过滤器

过滤器说明示例
default设置默认值{{ value|default:“默认值” }}
length返回长度{{ list|length }}
date日期格式化{{ date|date:“Y-m-d” }}
truncatewords截断字符串{{ text|truncatewords:30 }}
safe禁用转义{{ html|safe }}
upper转大写{{ string|upper }}
lower转小写{{ string|lower }}
capfirst首字母大写{{ string|capfirst }}

3.3 自定义模板标签和过滤器

python"># blog/templatetags/blog_tags.py
from django import template
from django.utils.html import mark_safe
import markdownregister = template.Library()# 自定义过滤器
@register.filter(name='markdown')
def markdown_format(text):return mark_safe(markdown.markdown(text))# 自定义简单标签
@register.simple_tag
def total_posts():from blog.models import Postreturn Post.objects.count()# 自定义包含上下文的标签
@register.inclusion_tag('blog/includes/latest_posts.html')
def show_latest_posts(count=5):from blog.models import Postlatest_posts = Post.objects.order_by('-publish')[:count]return {'latest_posts': latest_posts}

四、模板继承

4.1 基础模板

<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>{% block title %}默认标题{% endblock %}</title>{% block css %}<link rel="stylesheet" href="{% static 'css/base.css' %}">{% endblock %}
</head>
<body><header>{% include 'includes/header.html' %}</header><div class="container"><main>{% block content %}{% endblock %}</main><aside>{% block sidebar %}{% include 'includes/sidebar.html' %}{% endblock %}</aside></div><footer>{% include 'includes/footer.html' %}</footer>{% block js %}<script src="{% static 'js/base.js' %}"></script>{% endblock %}
</body>
</html>

4.2 页面模板

<!-- templates/blog/post_detail.html -->
{% extends 'base.html' %}
{% load blog_tags %}{% block title %}{{ post.title }}{% endblock %}{% block css %}{{ block.super }}<link rel="stylesheet" href="{% static 'css/post.css' %}">
{% endblock %}{% block content %}<article class="post-detail"><h1>{{ post.title }}</h1><div class="meta"><span>作者:{{ post.author.username }}</span><span>发布时间:{{ post.publish|date:"Y-m-d H:i" }}</span><span>分类:{{ post.category.name }}</span></div><div class="content">{{ post.body|markdown }}</div><div class="tags">{% for tag in post.tags.all %}<span class="tag">{{ tag.name }}</span>{% endfor %}</div></article>{% show_latest_posts 5 %}
{% endblock %}

五、静态文件处理

5.1 静态文件配置

python"># settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / "static",
]
STATIC_ROOT = BASE_DIR / 'staticfiles'# 开发环境media文件配置
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'

5.2 静态文件使用示例

<!-- templates/blog/includes/sidebar.html -->
{% load static %}<div class="sidebar"><div class="profile"><img src="{% static 'images/avatar.png' %}" alt="头像"><h3>{{ user.username }}</h3></div><div class="categories"><h3>文章分类</h3><ul>{% for category in categories %}<li><a href="{% url 'blog:category' category.slug %}">{{ category.name }}<span>({{ category.posts.count }})</span></a></li>{% endfor %}</ul></div>
</div>

5.3 CSS示例

/* static/css/base.css */
:root {--primary-color: #007bff;--secondary-color: #6c757d;--background-color: #f8f9fa;
}body {font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;line-height: 1.6;color: #333;background-color: var(--background-color);
}.container {max-width: 1200px;margin: 0 auto;padding: 0 15px;display: grid;grid-template-columns: 3fr 1fr;gap: 30px;
}/* 响应式设计 */
@media (max-width: 768px) {.container {grid-template-columns: 1fr;}
}

5.4 JavaScript示例

// static/js/base.js
document.addEventListener('DOMContentLoaded', function() {// 处理导航菜单const toggleMenu = document.querySelector('.toggle-menu');const nav = document.querySelector('nav');if (toggleMenu) {toggleMenu.addEventListener('click', function() {nav.classList.toggle('active');});}// 处理文章点赞const likeButtons = document.querySelectorAll('.like-button');likeButtons.forEach(button => {button.addEventListener('click', async function() {const postId = this.dataset.postId;try {const response = await fetch(`/api/posts/${postId}/like/`, {method: 'POST',headers: {'X-CSRFToken': getCookie('csrftoken')}});const data = await response.json();this.querySelector('.like-count').textContent = data.likes;} catch (error) {console.error('Error:', error);}});});
});

六、最佳实践

  1. 模板组织:

    • 使用清晰的目录结构
    • 根据功能模块划分模板
    • 复用代码放入includes目录
  2. 性能优化:

    • 使用模板片段缓存
    • 合理使用模板继承
    • 避免过多的模板嵌套
  3. 安全考虑:

    • 默认启用HTML转义
    • 谨慎使用safe过滤器
    • 注意XSS攻击防范

七、常见问题和解决方案

  1. 静态文件不显示:
python"># urls.py (开发环境)
from django.conf import settings
from django.conf.urls.static import staticif settings.DEBUG:urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
  1. 模板找不到:

    • 检查TEMPLATES设置
    • 确认模板文件位置
    • 检查应用是否已安装
  2. 上下文处理器:

python"># blog/context_processors.py
def categories(request):from blog.models import Categoryreturn {'categories': Category.objects.all()}

八、作业和练习

  1. 创建一个完整的博客首页模板
  2. 实现文章详情页模板
  3. 添加分类和标签侧边栏
  4. 实现评论系统模板
  5. 添加分页功能

怎么样今天的内容还满意吗?再次感谢朋友们的观看,关注GZH:凡人的AI工具箱,回复666,送您价值199的AI大礼包。最后,祝您早日实现财务自由,还请给个赞,谢谢!


http://www.ppmy.cn/server/150137.html

相关文章

软包拆垛自动化:深度视觉与智能算法如何重塑行业格局?

在现代工业生产和物流场景中&#xff0c;自动化拆垛已成为提升效率和降低人工操作风险的关键环节。特别是在涉及软包、纸箱、麻包袋等不规则物体的行业&#xff0c;如塑胶粒子、化肥、食品加工等。 软包拆垛的行业挑战 软包、纸箱等不规则物体在堆垛时由于形状不规则、材质多…

UE5 C+、C++、C# 构造方法区别示例

我们对比一下UE C、C 、C#的构造方法&#xff1a; 1. UE4 C例子&#xff1a; // 声明和构造合并在一起static ConstructorHelpers::FObjectFinder<UTexture2D> CrosshairTexObj(TEXT("/Game/Path"));// 使用加载的资源UTexture2D* Texture CrosshairTexObj.…

掌握 MySQL 事务:ACID、隔离级别详解

一、前言 事务是关系型数据库中的重要概念&#xff0c;用于保证一组数据库操作作为一个单独的工作单元来执行。无论是银行转账、订单处理还是复杂的数据修改&#xff0c;事务都能保证操作的一致性和完整性。 本文将带您从基础概念到高级技巧&#xff0c;全面了解 MySQL 事务的…

AI开源南京分享会回顾录

AI 开源南京分享会&#xff0c;已于2024年11月30日下午在国浩律师&#xff08;南京&#xff09;事务所5楼会议厅成功举办。此次活动由 KCC南京、PowerData、RISC-Verse 联合主办&#xff0c;国浩律师&#xff08;南京&#xff09;事务所协办。 活动以“开源视角的 AI 对话”为主…

docker简单私有仓库的创建

1&#xff1a;下载Registry镜像 导入镜像到本地中 [rootlocalhost ~]# docker load -i registry.tag.gz 进行检查 2&#xff1a;开启Registry registry开启的端口号为5000 [rootlocalhost ~]# docker run -d -p 5000:5000 --restartalways registry [rootlocalhost ~]# dock…

了解ARM的千兆以太网——RK3588

1. 简介 本文并不重点讲解调试内容&#xff0c;重点了解以太网在ARM设计中的框架以及在设备树以及驱动的一个整体框架。了解作为一个驱动开发人员当拿到一款未开发过的ARM板卡应该怎么去把网卡配置使用起来。 2. 基础知识介绍 在嵌入式ARM中实现以太网的解决方案通常有以下两种…

C++----入门篇

引言 C是在C的基础之上&#xff0c;容纳进去了面向对象编程思想&#xff0c;并增加了许多有用的库&#xff0c;以及编程范式等。熟悉C语言之后&#xff0c;对C学习有一定的帮助&#xff0c;本章节主要目标&#xff1a; 1. 补充C语言语法的不足&#xff0c;以及C是如何对C语言…

OpenCV 图像处理(一)

本章为 OpenCV 图像入门&#xff0c;主要讲解了如何加载图片&#xff0c;显示图片和保存图片。 读取图像 使用 cv.imread() 函数读取一张图像。 cv.IMREAD_COLOR&#xff1a;加载彩色图像&#xff0c;任何图像的透明度都会被忽略&#xff0c;它是默认标志&#xff1b;cv.IMRE…