关于python:Django-Rest-Framework – 如何将不相关模型中的查询集序列化为嵌套序列化程序

Django-Rest-Framework - How to serialize queryset from an unrelated model as nested serializer

我正在尝试根据父模型的某些条件(而不是外键)向现有序列化程序添加嵌套序列化程序。用例是返回一个带有"researchtemplate"对象数组的"research"对象,该数组通过对postgres arrayfield进行筛选来标识。

模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Research(TimeStampedModel):
    category = models.CharField(max_length=100, choices=RESEARCH_TEMPLATE_CATEGORIES, default='quote')
    body = models.CharField(max_length=1000, blank=True, default='') #The body of text comprising the nugget
    additionaldata = JSONField(null=True) # all the varying values to be merged into a wrapper

    def __str__(self):
        return self.body

    class Meta:
        ordering = ('created',)

class ResearchTemplate(TimeStampedModel):
    template = models.TextField(blank=True, default='')
    category = models.CharField(max_length=100, choices=RESEARCH_TEMPLATE_CATEGORIES, default='quote')
    mergefields = ArrayField(models.CharField(max_length=200), blank=True)

    def save(self, *args, **kwargs):
        merges = re.findall("{{(.*?)}}", self.template) #get all the template names from within the mustaches
        self.mergefields = list(set(merges)) #TODO: Make Unique
        super(TimeStampedModel, self).save(*args, **kwargs)

    def __str__(self):
        return self.wrapper

    class Meta:
        ordering = ('created',)

串行器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class ResearchSerializer(serializers.ModelSerializer):
        templates = ResearchTemplateSerializer(many=True)

        class Meta:
            model = Research
            fields = ('id', 'created', 'speaker', 'body', 'templates')

class ResearchTemplateSerializer(serializers.RelatedField):
        def get_queryset(self, values):
            return ResearchTemplate.objects.filter(mergefields__contained_by=['django']) #This must an array of keys from the Research object's JSON field

        class Meta:
            model = ResearchTemplate
            fields = ('id', 'template')

我已经能够在有外键映射的情况下嵌套序列化程序,但是无法使用自定义查询集进行嵌套。也许我没有正确地思考这个问题,我需要在研究模型上建立某种形式的"关系"领域。

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


您可以使用DRF的SerializerMethodFieldhttp://www.django-rest-framework.org/api-guide/fields/serializermethodfield。

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

然后将您的ResearchSerializer替换为:

1
2
3
4
5
6
7
8
9
10
11
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