Django 模板分割及多语言支持案例【需求文档】-->【实现方案】

Django 模板分割及多语言支持案例

这个案例旨在提供一个清晰的示范,展示如何将复杂的页面分解为多个可复用的模板组件,使代码更加模块化和易于管理。希望这篇案例文章对你有所帮助。

概述
在 Django 项目开发中,使用模板分割和多语言支持能有效提升代码的可维护性和用户体验。本案例通过一个简单的博客项目,展示如何将 Django 模板拆分为多个文件,并实现多语言支持。

需求文档

  1. 背景
    在开发Django项目时,将模板分割成多个文件并实现多语言支持是提高代码可维护性和用户体验的重要方法。本项目旨在展示如何使用Django模板进行模块化开发和多语言支持。通过一个简单的博客项目,我们将实现页面分割、文章列表显示及商品信息展示,并根据语言切换进行动态更新。

  2. 功能需求
    2.1 基础模板

功能:存储页面的基础配置,提供页面结构和通用样式。

文件名:base.html

详细描述:

包含HTML头部信息。

提供通用的样式定义。

定义内容插入块 {% block content %},供其他页面继承和填充内容。

2.2 主页模板

功能:显示主页内容,包含语言切换选项和文章列表。

文件名:home.html

详细描述:

继承自 base.html。

定义页面标题块 {% block title %}。

显示当前语言。

提供语言切换下拉菜单。

插入文章列表模板 {% include “article_list.html” %}。

2.3 文章列表模板

功能:循环显示文章列表,根据当前语言显示相应的文章标题和概括。

文件名:article_list.html

详细描述:

使用 {% for %} 循环显示所有文章。

根据当前语言显示中文或英文文章标题及概括。

插入相应语言的商品列表模板 {% include “products_list_cn.html” %} 或 {% include “products_list_en.html” %}。

2.4 中文商品列表模板

功能:显示文章中的商品列表,最多显示5个商品。

文件名:products_list_cn.html

详细描述:

根据是否存在商品标题,动态插入商品部分模板 {% include “products_part_1_cn.html” %} 至 {% include “products_part_5_cn.html” %}。

2.5 商品部分模板

功能:显示具体的商品信息。

文件名:products_part_1_cn.html 至 products_part_5_cn.html

详细描述:

显示商品标题、概括和图片。

根据商品信息动态生成页面内容。

  1. 界面展示
    3.1 主页

当前语言:显示当前选择的语言。

语言切换:提供语言选择下拉菜单,用户可切换语言。

文章列表:根据选择的语言显示对应的文章标题和概括。

商品列表:根据文章显示对应的商品列表和详细信息。

3.2 文章与商品展示

文章标题:根据语言显示中文或英文标题。

文章概括:显示文章的简短概括,并根据语言切换。

商品信息:根据语言动态显示商品标题、概括和图片。

  1. 业务逻辑
    4.1 模板继承

home.html 继承自 base.html,提供页面的基础结构和通用样式。

使用 {% block title %} 和 {% block content %} 定义可插入内容。

4.2 语言切换

在 home.html 中提供语言切换下拉菜单,并通过 JavaScript 实现页面语言切换。

根据选择的语言参数 current_language 动态加载文章和商品内容。

4.3 文章与商品显示

使用 {% for article in articles %} 循环遍历所有文章。

根据 current_language 判断显示中文或英文的文章标题和概括。

根据文章中的商品信息,动态加载相应的商品部分模板。

  1. 总结
    通过本需求文档,我们详细描述了Django项目中模板分割与多语言支持的实现方法。项目包含基础模板、主页模板、文章列表模板和商品部分模板,并通过语言切换动态加载对应内容,提升了代码的可维护性和用户体验。

具体实现

基础模板:base.html
基础模板 base.html 用于存储页面的基础配置,并可被其他页面继承和调用。它包含了 HTML 头部信息和页面主体结构:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>{% block title %}主页{% endblock %}</title><!-- Google Fonts --><link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet" /><!-- Tailwind CSS CDN --><script src="https://cdn.tailwindcss.com"></script><style>body {font-family: 'Roboto', sans-serif;}.hover-arrow::after {content: '>';color: #a0aec0;right: 0px;position: absolute;font-weight: bold;font-size: 24px;width: 25px;height: 36px;top: 25px;}</style>
</head>
<body class="bg-gray-900 text-white"><div class="max-w-3xl mx-auto py-8 px-4">{% block content %}{% endblock %}</div>
</body>
</html>

主页模板:home.html
主页模板 home.html 继承自 base.html,并包含页面标题、语言切换选项和文章列表:

{% extends "base.html" %}{% block title %}主页{% endblock %}{% block content %}<div class="mb-4"><span class="text-white text-xl font-bold">当前语言: {{ current_language }}</span></div><div class="mb-4"><label for="language-select" class="text-white text-xl">选择语言: </label><select id="language-select" onchange="changeLanguage(this)"><option value="cn" {% if current_language == 'cn' %}selected{% endif %}>简体中文</option><option value="en" {% if current_language == 'en' %}selected{% endif %}>English</option></select></div>{% include "article_list.html" %}<script>function changeLanguage(select) {const lang = select.value;const url = new URL(window.location.href);url.searchParams.set('lang', lang);window.location.href = url.toString();}</script>
{% endblock %}

文章列表模板:article_list.html
article_list.html 用于循环显示文章列表,根据当前语言显示相应的标题和文章概括,并插入商品列表模板:

{% for article in articles %}
<br>{% if article.title_en and current_language == 'en' %} <div class="flex items-center mb-6"><div class="w-8 h-8 bg-orange-500 rounded-full flex items-center justify-center"><span class="text-white text-xl font-bold">Hot</span></div><div class="ml-3"><h1 class="text-lg font-bold"><a href="/article/{{ article.id }}/?lang={{ current_language }}" class="text-blue-400 hover:underline">{{ article.title_en }}</a></h1></div>
</div>
<p class="text-gray-400 mb-6 leading-relaxed">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% with summary=article.summary_en|default_if_none:""|slice:":80" %}{{ summary|ljust:80 }}{% endwith %}
</p>
{% include "products_list_en.html" %}
{% endif %}{% if article.title_cn and current_language == 'cn' %} <div class="flex items-center mb-6"><div class="w-8 h-8 bg-orange-500 rounded-full flex items-center justify-center"><span class="text-white text-xl font-bold"></span></div><div class="ml-3"><h1 class="text-lg font-bold"><a href="/article/{{ article.id }}/?lang={{ current_language }}" class="text-blue-400 hover:underline">{{ article.title_cn }}</a></h1></div>
</div>
<p class="text-gray-400 mb-6 leading-relaxed">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% with summary=article.summary_cn|default_if_none:""|slice:":80" %}{{ summary|ljust:80 }}{% endwith %}
</p>
{% include "products_list_cn.html" %}
{% endif %}{% endfor %}

商品列表模板:products_list_cn.html
products_list_cn.html 用于显示中文商品列表。根据该篇文章是否插入商品,最多5个,最少0个 来进行显示:

<div class="space-y-4">{% if article.product_1_title_cn %}{% include "products_part_1_cn.html" %}{% endif %}{% if article.product_2_title_cn %}{% include "products_part_2_cn.html" %}{% endif %}{% if article.product_3_title_cn %}{% include "products_part_3_cn.html" %}{% endif %}{% if article.product_4_title_cn %}{% include "products_part_4_cn.html" %}{% endif %}{% if article.product_5_title_cn %}{% include "products_part_5_cn.html" %}{% endif %}
</div>

商品部分模板:products_part_1_cn.html
products_part_1_cn.html 用于显示文章中的第一个商品:

<a href="{{ article.product_1_link_cn }}" class="block"><div class="relative bg-gray-800 p-4 rounded-lg hover:bg-gray-700 cursor-pointer hover-arrow transition-all"><h2 class="text-lg font-bold mb-1">{{ article.product_1_title_cn }}</h2><p class="text-gray-400 text-sm" style="padding-right: 120px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% with summary=article.product_1_summary_cn|default_if_none:""|slice:":80" %}{{ summary|ljust:80 }}{% endwith %}</p>{% if article.image_1 %}<div class="absolute top-2 right-12 w-16 h-16" {% if article.tag_choice_1 == 'circle_image' %} style="border-radius: 50%; overflow: hidden;" {% elif article.tag_choice_1 == 'square_image' %} style="border-radius: 0;" {% elif article.tag_choice_1 == 'triangle_image' %} style="clip-path: polygon(50% 0%, 0% 100%, 100% 100%);" {% elif article.tag_choice_1 == 'pentagon_image' %} style="clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);" {% elif article.tag_choice_1 == 'hexagon_image' %} style="clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);" {% else %} style="display: none;" {% endif %}><img src="{{ article.image_1 }}" alt="Article Image" class="w-full h-full object-cover"></div>{% endif %}</div>
</a>

商品部分模板:products_part_2_cn.html - products_part_5_cn.html
商品部分模板的配置方式类似于 products_part_1_cn.html。对于每个商品部分,都需要创建相应的模板文件 products_part_2_cn.html 到 products_part_5_cn.html,并按照上述方式进行配置。

这样一来,通过基础模板、主页模板、文章列表模板和商品部分模板的组合,可以实现页面的模块化开发和多语言支持,提高代码的可维护性和用户体验。

英文商品列表模板:products_list_en.html
products_list_en.html 用于显示英文商品列表。根据该篇文章是否插入商品,最多5个,最少0个来进行显示:

<div class="space-y-4">{% if article.product_1_title_en %}{% include "products_part_1_en.html" %}{% endif %}{% if article.product_2_title_en %}{% include "products_part_2_en.html" %}{% endif %}{% if article.product_3_title_en %}{% include "products_part_3_en.html" %}{% endif %}{% if article.product_4_title_en %}{% include "products_part_4_en.html" %}{% endif %}{% if article.product_5_title_en %}{% include "products_part_5_en.html" %}{% endif %}
</div>

英文商品部分模板:products_part_1_en.html
products_part_1_en.html 用于显示文章中的第一个英文商品:

<a href="{{ article.product_1_link_en }}" class="block"><div class="relative bg-gray-800 p-4 rounded-lg hover:bg-gray-700 cursor-pointer hover-arrow transition-all"><h2 class="text-lg font-bold mb-1">{{ article.product_1_title_en }}</h2><p class="text-gray-400 text-sm" style="padding-right: 120px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{% with summary=article.product_1_summary_en|default_if_none:""|slice:":80" %}{{ summary|ljust:80 }}{% endwith %}</p>{% if article.image_1 %}<div class="absolute top-2 right-12 w-16 h-16" {% if article.tag_choice_1 == 'circle_image' %} style="border-radius: 50%; overflow: hidden;" {% elif article.tag_choice_1 == 'square_image' %} style="border-radius: 0;" {% elif article.tag_choice_1 == 'triangle_image' %} style="clip-path: polygon(50% 0%, 0% 100%, 100% 100%);" {% elif article.tag_choice_1 == 'pentagon_image' %} style="clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);" {% elif article.tag_choice_1 == 'hexagon_image' %} style="clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);" {% else %} style="display: none;" {% endif %}><img src="{{ article.image_1 }}" alt="Article Image" class="w-full h-full object-cover"></div>{% endif %}</div>
</a>

英文商品部分模板:products_part_2_en.html - products_part_5_en.html
英文商品部分模板的配置方式与 products_part_1_en.html 类似。对于每个商品部分,都需要创建相应的模板文件 products_part_2_en.html 到 products_part_5_en.html,并按照上述方式进行配置。

通过这些模板的组合和使用,可以学习如何在 Django 项目中使用模板继承与分割,以及如何实现多语言支持,从而提升项目的可维护性和用户体验。

为什么会使用这种自定义的方式?

虽然Django自带的翻译机制(i18n)是一个非常强大的工具,适用于大多数情况下的多语言支持,但在特定的需求和场景下,本文所采用的方法却有其不可替代的优势。以下是这些特定场景和需求的详细分析:

  1. 即时数据展示和内容管理
    优点:
    直接展示数据库内容:通过条件判断直接展示数据库中的多语言内容,无需在翻译文件之间进行中转,这可以确保数据的实时性和一致性。

便于内容管理:在一些需要频繁更新的项目中,如新闻网站或电子商务平台,内容管理人员可以直接在数据库中更新不同语言的内容,无需等待翻译文件的生成和编译。

  1. 灵活的模板定制
    优点:
    模板自定义:本文方法允许对不同语言的模板进行高度定制,例如,中文和英文模板可以有完全不同的布局和样式。这在一些文化差异较大的项目中尤为重要。

高度灵活:开发者可以针对不同语言版本进行不同的样式和内容调整,而不必受限于统一的翻译文件结构。这种灵活性在需要针对不同市场进行本地化优化时非常有用。

  1. 快速开发和原型设计
    优点:
    快速实现:不需要配置和管理翻译文件,开发者可以快速实现多语言支持,适用于项目初期的快速原型设计和验证。

低学习曲线:对于刚接触Django的开发者来说,不需要额外学习i18n的相关知识即可实现多语言支持,降低了开发难度和时间成本。

  1. 特定业务逻辑需求
    优点:
    复杂业务逻辑处理:在某些特定的业务需求下,需要在展示内容时进行复杂的逻辑判断和处理。例如,不同语言版本可能需要展示不同的广告或促销信息,这种情况下,通过模板条件判断可以更灵活地实现业务需求。

可扩展性:本文方法可以针对特定业务需求进行扩展,如在不同语言版本中显示不同的商品列表和内容,满足更加个性化的需求。

  1. 无需额外配置和依赖
    优点:
    简化配置:不需要依赖Django的中间件和配置,减少了系统依赖和配置复杂度,适用于一些简单的项目和开发环境。

减少出错可能:由于无需生成和编译翻译文件,减少了在这一步骤中可能出现的错误和不一致问题。

总结
虽然Django自带的翻译机制是处理多语言支持的最佳实践,但在特定需求和场景下,本文的方法提供了无法替代的灵活性和便捷性。这种方法在处理实时数据、定制化模板、快速开发和特定业务需求上具有明显优势,适用于一些需要快速实现、频繁更新和高度定制的项目。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/63684.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

wxWidgets使用wxStyledTextCtrl(Scintilla编辑器)的正确姿势

开发CuteMySQL/CuteSqlite开源客户端的时候&#xff0c;需要使用Scintilla编辑器&#xff0c;来高亮显示SQL语句&#xff0c;作为C/C领域最成熟稳定又小巧的开源编辑器&#xff0c;Scintilla提供了强大的功能&#xff0c;wxWidgets对Scintilla进行包装后的是控件类&#xff1a;…

构建高性能异步任务引擎:FastAPI + Celery + Redis

在现代应用开发中&#xff0c;异步任务处理是一个常见的需求。无论是数据处理、图像生成&#xff0c;还是复杂的计算任务&#xff0c;异步执行都能显著提升系统的响应速度和吞吐量。今天&#xff0c;我们将通过一个实际项目&#xff0c;探索如何使用 FastAPI、Celery 和 Redis …

介绍 Html 和 Html 5 的关系与区别

HTML&#xff08;HyperText Markup Language&#xff09;是构建网页的标准标记语言&#xff0c;而 HTML5 是 HTML 的最新版本&#xff0c;包含了一些新的功能、元素、API 和属性。HTML5 相对于早期版本的 HTML&#xff08;比如 HTML4&#xff09;有许多重要的改进和变化。以下是…

【win10+RAGFlow+Ollama】搭建本地大模型助手(教程+源码)

一、RAGFlow简介 RAGFlow是一个基于对文档深入理解的开源RAG&#xff08;Retrieval-augmented Generation&#xff0c;检索增强生成&#xff09;引擎。 主要作用&#xff1a; 让用户创建自有知识库&#xff0c;根据设定的参数对知识库中的文件进行切块处理&#xff0c;用户向大…

qwt 之 QwtPlotPicker

QwtPlotMarker 和 QwtPlotPicker 是 Qwt 库中用于增强 QwtPlot 功能的两个重要类。它们分别用于在图中添加标记和实现交互式的选择或拖动功能。 QwtPlotPicker 提供了交互式的选择工具&#xff0c;它允许用户通过鼠标点击或拖动来选择图表中的数据点或区域。这对于实现缩放、平…

C/C++圣诞树

系列文章 序号直达链接1C/C爱心代码2C/C跳动的爱心3C/C李峋同款跳动的爱心代码4C/C满屏飘字表白代码5C/C大雪纷飞代码6C/C烟花代码7C/C黑客帝国同款字母雨8C/C樱花树代码9C/C奥特曼代码10C/C精美圣诞树11C/C俄罗斯方块12C/C贪吃蛇13C/C孤单又灿烂的神-鬼怪14C/C闪烁的爱心15C…

lua dofile 传参数

cat 1.lua arg[1] 111 arg[2] 222 dofile(./2.lua) cat 2.lua print("First argument is: " .. arg[1]) print("Second argument is: " .. arg[2]) 执行 lua 1.lua&#xff0c;结果为&#xff1a; First argument is: 111 Second argument is: 222 l…

电商数据流通的未来:API接口的智能化与自动化趋势

在数字化时代&#xff0c;电子商务行业正在以前所未有的速度发展&#xff0c;而API&#xff08;应用程序编程接口&#xff09;接口作为电商领域的重要组成部分&#xff0c;其应用和发展趋势也日益受到关注。API接口作为电商系统与外部服务或平台交互的桥梁&#xff0c;对电商数…

投标心态:如何在“标海战术”中保持清醒的头脑?

在竞争激烈的市场环境下&#xff0c;“标海战术”——即大规模参与投标——已经成为许多企业争取市场份额的重要策略。然而&#xff0c;盲目追求投标数量可能导致资源浪费、团队疲劳以及战略目标的模糊化。在这种高强度的竞争模式中&#xff0c;如何保持清醒的头脑&#xff0c;…

【苍穹外卖】学习心得体会-随笔

前言 写了很久&#xff0c;终于可以完整运行项目了&#xff0c;记录下这几天的心得体会回顾一下知识点 第一天、Git 分布式版本控制工具 一、Git概述 定义&#xff1a;是分布式版本控制工具&#xff0c;用于管理软件开发中的源代码文件&#xff0c;像Java类、xml文件、html…

windows C#-使用构造函数

实例化类或结构时&#xff0c;将会调用其构造函数。 构造函数与该类或结构具有相同名称&#xff0c;并且通常初始化新对象的数据成员。 在下面的示例中&#xff0c;通过使用简单构造函数定义了一个名为 Taxi 的类。 然后使用 new 运算符对该类进行实例化。 在为新对象分配内存…

研发效能DevOps: Vite 使用 Element Plus

目录 一、实验 1.环境 2.初始化前端项目 3.安装 vue-route 4.安装 pinia 5.安装 axios 6.安装 Element Plus 7.gitee创建工程 8. 配置路由映射 9.Vite 使用 Element Plus 二、问题 1.README.md 文档推送到gitee未自动换行 2.访问login页面显示空白 3.表单输入账户…

5G 模组 RG500Q常用AT命令

5G 模组 RG500Q常用AT命令 5G 模组 RG500Q常用AT命令 at ATQNWPREFCFG\"mode_pref\",nr5g && sleep 1 at ATQNWPREFCFG\"nr5g_band\",79 && sleep 1 at atqnwlock\"commo…

NVIDIA DeepStream插件之Gst-nvtracker

NVIDIA DeepStream插件之Gst-nvtracker 1. 源由2. 基础知识3. Gst-nvtracker插件3.1 插件参数3.2 插件API接口 4. 分析问题5. 总结6. 参考资料 1. 源由 这篇的主要目的是稍微吐槽下NVIDIA的设计&#xff0c;当然其实他们做的还是不错的&#xff08;从系统架构设计角度看&#…

进程内存转储工具|内存镜像提取-取证工具

1.内存转储&#xff0c;内存转储&#xff08;Memory Dump&#xff09;是将计算机的物理内存&#xff08;RAM&#xff09;内容复制到一个文件中的过程&#xff0c;这个文件通常被称为“内存转储文件”或“核心转储文件”&#xff08;Core Dump&#xff09;,内存转储的主要目的是…

Lua语言入门 - Lua 面向对象

Lua 面向对象 面向对象编程&#xff08;Object Oriented Programming&#xff0c;OOP&#xff09;是一种非常流行的计算机编程架构&#xff0c;通过创建和操作对象来设计应用程序。 以下几种编程语言都支持面向对象编程&#xff1a; CJavaObjective-CSmalltalkC#Ruby Lua 是…

Pyqt6在lineEdit中输入文件名称并创建或删除JSON文件

1、创建JSON文件 代码 import osdef addModulekeyWordFile(self):if "" ! self.lineEdit_module.text():moduleFile self.lineEdit_module.text() .jsonelse:self.toolLogPrinting(请输入模块名称)returnfilePath modulekeyWordFileDir moduleFileif os.path.e…

【Leetcode 热题 100】236. 二叉树的最近公共祖先

问题背景 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 最近公共祖先的定义为&#xff1a;对于有根树 T T T 的两个节点 p p p、 q q q&#xff0c;最近公共祖先表示为一个节点 x x x&#xff0c;满足 x x x 是 p p p、 q q q 的祖先且 x x x 的深度尽可能大…

数据结构--堆的向上调整和向下调整

文章目录 1.完全二叉树2.堆向上调整3.堆向下调整4.测试代码 1.完全二叉树 下面的这个就是对于我们的完全二叉树的这个逻辑结构和物理结构的说明&#xff1a; 逻辑结构就是我们自己认为的进行购想出来的&#xff1b; 但是这个物理结构却是我们的这个数据结构在内存里面的真是…

智能挂号系统设计典范:SSM 结合 Vue 在医院的应用实现

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了医院预约挂号系统的开发全过程。通过分析医院预约挂号系统管理的不足&#xff0c;创建了一个计算机管理医院预约挂号系统的方案。文章介绍了医院预约挂号系统的系…