如何在Django中实现可复用的带业务逻辑的页面片段?
你需要的这种自带逻辑、可在任意页面嵌入的「迷你视图」类片段,有3种常用实现方案,Class Mixin可以实现但适配场景有限,具体说明如下:

方案1:自定义包含标签(最适配你的需求)
这是Django原生专门为该场景设计的功能,逻辑和模板完全封装,不需要修改父视图的任何代码:
- 第一步在你的应用目录下新建
templatetags文件夹,新增__init__.py(空文件即可)和自定义标签文件,比如fragment_tags.py - 编写标签的逻辑代码:
from django import template from your_app.models import Article # 替换为你自己的模型 register = template.Library() # 绑定该标签对应的片段模板 @register.inclusion_tag('fragments/recommended_articles.html') def show_recommended_articles(count=5): # 这里写你需要的独立逻辑,比如查询推荐文章 recommended_articles = Article.objects.filter(is_published=True).order_by('-view_count')[:count] # 返回的变量会直接传入绑定的片段模板 return {'articles': recommended_articles}
- 新建片段模板
templates/fragments/recommended_articles.html,正常渲染返回的articles变量即可 - 使用时任意页面先加载标签库
{% load fragment_tags %},直接调用即可:{% show_recommended_articles 3 %},还可以自定义传入参数调整展示数量等规则。
方案2:上下文处理器(适合全站点通用的片段)
如果你的片段需要在全站所有页面显示,可以用上下文处理器全局注入数据,配合{% include %}使用:
- 新建上下文处理器文件
your_app/context_processors.py:
from your_app.models import Article def global_recommended_articles(request): return { 'global_recommended_articles': Article.objects.filter(is_published=True).order_by('-view_count')[:5] }
- 在项目配置文件
settings.py的TEMPLATES.OPTIONS.context_processors列表中,新增上述文件的路径,之后所有模板都可以直接使用{{ global_recommended_articles }}变量,不用每个视图单独传值。
注意:该方案会在所有页面请求时都执行一次逻辑查询,如果你的片段只在部分页面使用,会造成不必要的性能消耗。
方案3:异步加载片段(适合逻辑较重的场景)
如果你的片段逻辑很复杂,查询耗时久,不想阻塞主页面渲染,可以用异步加载的方案:
- 单独写一个视图,专门返回该片段的HTML:
from django.shortcuts import render from your_app.models import Article def recommended_articles_fragment(request, count=5): recommended_articles = Article.objects.filter(is_published=True).order_by('-view_count')[:count] return render(request, 'fragments/recommended_articles.html', {'articles': recommended_articles})
- 为该视图配置独立路由,之后在需要嵌入的页面用HTMX等工具异步加载即可:
<div hx-get="/fragments/recommended-articles/3" hx-trigger="load"></div>
该方案主页面渲染完成后才会加载片段,还可以自定义添加加载动画、缓存等规则。
关于Class Mixin的说明
Class Mixin可以实现需求,但适用场景有限:你可以写一个Mixin给类视图统一注入片段需要的上下文变量:
class RecommendedArticlesMixin: def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['recommended_articles'] = Article.objects.filter(is_published=True).order_by('-view_count')[:5] return context
之后所有需要用到该片段的类视图都继承这个Mixin即可,但如果要新增使用场景就要修改对应视图,不如自定义包含标签灵活。
内容的提问来源于stack exchange,提问作者user16909741
相关产品推荐
相关产品推荐

