如何在Django项目级base.html中随机展示应用级Quotes模型的名言?
Django全局随机名言实现思路
针对你的场景,有三个实用的方案可以把应用级Quotes模型的随机条目传递给根目录的base.html,每个方案各有适用场景,你可以根据项目情况选择:
方案1:全局上下文处理器(最推荐)
这个方法能让所有模板自动获取随机名言变量,不用在每个视图里重复写逻辑,完美适配base.html被所有应用模板继承的场景。
步骤:
- 在你的应用目录下创建
context_processors.py文件,写入以下代码:
from .models import Quotes from random import randint def random_quote(request): # 小数据量用order_by('?')简单直接,大数据量换下面的高效写法 # quote = Quotes.objects.order_by('?').first() # 大数据量推荐写法:先统计总数,再取随机索引 count = Quotes.objects.count() if count == 0: return {'random_quote': None} random_index = randint(0, count - 1) quote = Quotes.objects.all()[random_index] return {'random_quote': quote}
- 打开项目根目录的
settings.py,找到TEMPLATES配置项,在OPTIONS的context_processors列表里添加处理器路径(假设你的应用叫quotes_app):
TEMPLATES = [ { # ...其他配置 'OPTIONS': { 'context_processors': [ # ...默认的处理器 'quotes_app.context_processors.random_quote', ], }, }, ]
- 直接在
base.html的名言Card里使用变量:
<div class="card"> <div class="card-body"> {% if random_quote %} <p class="card-text">{{ random_quote.content }}</p> <footer class="blockquote-footer">{{ random_quote.author }}</footer> {% else %} <p class="card-text">暂无名言</p> {% endif %} </div> </div>
方案2:自定义模板标签(灵活可控)
如果不想全局传递变量,或者需要在模板里手动控制是否加载随机名言,可以用自定义模板标签。
步骤:
- 在应用目录下创建
templatetags文件夹,里面必须有__init__.py(空文件即可),再创建quotes_tags.py文件:
from django import template from ..models import Quotes from random import randint register = template.Library() @register.simple_tag def get_random_quote(): count = Quotes.objects.count() if count == 0: return None random_index = randint(0, count - 1) return Quotes.objects.all()[random_index]
- 在
base.html的开头加载标签库,然后调用标签获取名言:
{% load quotes_tags %} <!-- 名言Card部分 --> <div class="card"> <div class="card-body"> {% get_random_quote as random_quote %} {% if random_quote %} <p class="card-text">{{ random_quote.content }}</p> <footer class="blockquote-footer">{{ random_quote.author }}</footer> {% else %} <p class="card-text">暂无名言</p> {% endif %} </div> </div>
方案3:视图基类(适合统一管理视图逻辑)
如果你的应用所有视图都继承同一个基类,可以在基类里统一添加名言变量,这样所有继承的视图都会把变量传给模板。
步骤:
- 在应用目录下创建视图基类:
from django.views.generic import TemplateView from .models import Quotes from random import randint class BaseQuoteView(TemplateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) count = Quotes.objects.count() if count > 0: random_index = randint(0, count - 1) context['random_quote'] = Quotes.objects.all()[random_index] else: context['random_quote'] = None return context
- 应用里的其他视图都继承这个基类:
class HomeView(BaseQuoteView): template_name = 'home.html' class AboutView(BaseQuoteView): template_name = 'about.html'
- 最后在
base.html里和方案1一样直接使用{{ random_quote }}变量即可。
内容的提问来源于stack exchange,提问作者Racz
相关产品推荐
相关产品推荐

