You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Django自定义过滤器支持{{ 对象.属性|过滤器 }}的简洁调用?

要实现{{ moderated_object.field_name | approved }}这种简洁的过滤器调用,你可以通过包装字段值为包含上下文信息的对象来实现,具体步骤如下:

  1. 定义一个包装类,用来存储字段值、所属对象和字段名:
class ModeratedValue:
    def __init__(self, value, instance, field_name):
        self.value = value
        self.instance = instance
        self.field_name = field_name
  1. 自定义字段描述符,让模型字段返回包装后的对象:
class ModeratedFieldDescriptor:
    def __init__(self, original_field):
        self.original_field = original_field
        self.field_name = None

    def __get__(self, instance, owner):
        if instance is None:
            return self
        # 获取原始字段值
        raw_value = self.original_field.__get__(instance, owner)
        # 返回包装后的对象,带上实例和字段名
        return ModeratedValue(raw_value, instance, self.field_name)

    def __set__(self, instance, value):
        # 保留字段的赋值逻辑
        self.original_field.__set__(instance, value)
  1. 在你的模型中,用这个描述符包装需要审核的字段:
from django.db import models

class ModeratedModel(models.Model):
    # 示例字段,假设对应审核状态字段为`title_approved`
    title = ModeratedFieldDescriptor(models.CharField(max_length=200))
    # 审核状态字段
    title_approved = models.BooleanField(default=False)

    content = ModeratedFieldDescriptor(models.TextField())
    content_approved = models.BooleanField(default=False)

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 给每个描述符设置字段名
        for name, attr in self.__class__.__dict__.items():
            if isinstance(attr, ModeratedFieldDescriptor):
                attr.field_name = name

    class Meta:
        abstract = True
  1. 最后编写自定义模板过滤器:
from django import template

register = template.Library()

@register.filter
def approved(moderated_value):
    # 只处理包装后的ModeratedValue对象
    if not isinstance(moderated_value, ModeratedValue):
        return moderated_value

    # 拼接审核状态字段名(比如title对应title_approved)
    approval_field = f"{moderated_value.field_name}_approved"
    # 检查是否通过审核
    if getattr(moderated_value.instance, approval_field, False):
        return moderated_value.value
    # 未通过则返回空字符串或默认值
    return ""

这样一来,在模板里直接写{{ moderated_object.title | approved }}就可以了——过滤器会自动从包装对象里拿到所属实例和字段名,检查对应的审核状态,只有通过时才返回字段值,否则返回空。

如果你的审核状态存储方式不同(比如存在关联模型而非同表字段),只需要修改approved过滤器里的逻辑,比如从关联表中查询审核状态即可。

内容的提问来源于stack exchange,提问作者Homunculus Reticulli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 01:36:34