【问题标题】:How can I serialize a queryset from an unrelated model as a nested serializer?如何将不相关模型中的查询集序列化为嵌套序列化程序?
【发布时间】:2017-08-04 04:28:26
【问题描述】:

我正在尝试根据父模型的某些标准,而不是外键,将嵌套序列化程序添加到现有序列化程序。用例是返回一个“Research”对象,其中包含一组“ResearchTemplate”对象,这些对象是通过在 Postgres ArrayField 上过滤来识别的。

模型


类研究(TimeStampedModel):
    类别 = models.CharField(max_length=100, 选择=RESEARCH_TEMPLATE_CATEGORIES, default='quote')
    body = models.CharField(max_length=1000, blank=True, default='') #组成金块的正文
    additionaldata = JSONField(null=True) # 所有不同的值都被合并到一个包装器中

    def __str__(self):
        返回self.body

    元类:
        排序 = ('创建',)

类研究模板(TimeStampedModel):
    模板=模型.TextField(空白=真,默认='')
    类别 = models.CharField(max_length=100, 选择=RESEARCH_TEMPLATE_CATEGORIES, default='quote')
    合并字段 = ArrayField(models.CharField(max_length=200), 空白=True)

    def 保存(自我,*args,**kwargs):
        merges = re.findall("{{(.*?)}}", self.template) #从胡须中获取所有模板名称
        self.mergefields = list(set(merges)) #TODO: Make Unique
        super(TimeStampedModel, self).save(*args, **kwargs)

    def __str__(self):
        返回 self.wrapper

    元类:
        排序 = ('创建',)

序列化器


类 ResearchSerializer(serializers.ModelSerializer):
        模板 = ResearchTemplateSerializer(many=True)

        元类:
            模型 = 研究
            fields = ('id', 'created', 'speaker', 'body', 'templates')

类 ResearchTemplateSerializer(serializers.RelatedField):
        def get_queryset(self, values):
            return ResearchTemplate.objects.filter(mergefields__contained_by=['django']) #这必须是来自 Research 对象的 JSON 字段的键数组

        元类:
            模型 = 研究模板
            字段 = ('id', '模板')

当有外键映射序列化程序时,我已经能够嵌套序列化程序,但是我无法使用自定义查询集这样做。也许我没有正确考虑这一点,我需要在研究模型上设置某种形式的“关系”字段。

如何使用从父模型指定的值嵌套从过滤器返回的所有行的序列化列表?

【问题讨论】:

    标签: python django postgresql serialization django-rest-framework


    【解决方案1】:

    您可以使用 DRF 的SerializerMethodField

    将您的 ResearchTemplateSerializer 定义为普通的 ModelSerializer,而不是 RelatedField

    然后用这个替换你的ResearchSerializer

    class ResearchSerializer(serializers.ModelSerializer):
        templates = serializers.SerializerMethodField()
    
        class Meta:
            model = Research
            fields = ('id', 'created', 'speaker', 'body', 'templates')
    
        def get_templates(self, obj):
            values = obj.get_values() # whatever your filter values are. obj is the Research instance
            templates = ResearchTemplate.objects.filter(mergefields__contained_by=values) # Or whatever queryset filter
            return ResearchTemplateSerializer(templates, many=True).data
    

    【讨论】:

    • 我不知道SerializerMethodField(),谢谢!我的很多问题的答案。
    猜你喜欢
    • 1970-01-01
    • 2012-05-31
    • 2021-03-29
    • 2016-09-17
    • 1970-01-01
    • 2020-09-29
    • 1970-01-01
    • 2020-07-30
    • 2016-03-01
    相关资源
    最近更新 更多