【问题标题】:choose serializer fields based on instance data根据实例数据选择序列化器字段
【发布时间】:2017-08-16 13:49:51
【问题描述】:

我正在尝试根据实例本身在我的 ModelSerializer 上动态包含/排除特定字段。所以,假设我有一个层次模型,它使用自连接来表示地理:

class TreeModel():
    name = CharField()
    kind = CharField(choices=['country', 'state', 'city'])
    parent = ForeignKey(self, related_name='children')

鉴于此,假设我想在种类为“州”时隐藏实例的“子”关系链接,然后在种类为“国家”时显示它。我尝试摆弄get_fields 方法,但没有奏效。

我希望这样做,因为在我的模型中,TreeModel 类的某些实例有数千个子级,而其他实例只有几个。我不想向孩子展示某些实例类型,因为它会降低性能,我只需要它们作为子集。谢谢

【问题讨论】:

  • 您想为检索请求或列表请求执行此操作吗?
  • 如果“检索”是指获取单个对象(详细视图与列表视图),那么是的,这正是我的意思。但是,考虑到我使用的序列化程序(JSONAPI),这也意味着列表视图中包含的每个单独对象通常都包含对每个字段的引用。 (这不是一个嵌套的序列化程序;我的意思是,如果我请求一个“混合类型”列表,它仍然需要根据列表中的每个单独的对象类型动态选择子字段。

标签: django-rest-framework


【解决方案1】:

This 是您正在寻找的。 DRF 允许您在序列化程序初始化时动态修改字段。

class TreeSerializer:
    def __init__(self , instance , *args , **kwargs ):
        super().__init__(instance , *args , **kwargs)
        if instance.kind == 'state':
            self.fields.pop('children')
        #Other Conditions

这个例子会成立,因为序列化器的第一个位置参数始终是模型实例。

还有另一种方法可以在不修改序列化程序的情况下执行此操作:使用Django signals。 这是我的answer 演示如何使用它们

【讨论】:

  • 感谢您的回复,但不是这样(我应该提到我首先阅读了文档。)您参考的部分演示了如何明确指定请求的字段;我希望将字段列表指定为实例本身的函数。如果该答案显示了如何访问类中的实例,那么是的,它会起作用。但它并没有显示出来。
  • 谢谢。我将接受这一点,因为它有效并回答了我提出的问题。事实证明,它并没有解决我遇到的问题,但这与 SO 是正交的。
【解决方案2】:
class TreeSerializer(serializers.ModelSerializer):
    def to_representation(self, instance):
        if instance.kind == 'state':
            self.fields.pop('children')
        return super().to_representation(instance)

【讨论】:

  • 您能否提供更多细节并对此进行解释?
猜你喜欢
  • 2017-07-30
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 2011-09-26
  • 1970-01-01
  • 2014-12-12
  • 1970-01-01
  • 2020-03-14
相关资源
最近更新 更多