外部キーではなく、親モデルのいくつかの基準に基づいて、ネストされたシリアライザーを既存のシリアライザーに追加しようとしています。ユースケースは、Postgres ArrayFieldでフィルタリングすることによって識別される「ResearchTemplate」オブジェクトの配列を持つ「Research」オブジェクトを返すことです。
モデル
class Research(TimeStampedModel): category = models.CharField(max_length = 100、choices = RESEARCH_TEMPLATE_CATEGORIES、default = 'quote') body = models。 CharField(max_length = 1000、blank = True、default = '')#ナゲットを構成するテキストの本文 additionaldata = JSONField(null = True)#ラッパーにマージされるすべての可変値 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)#口ひげ内からすべてのテンプレート名を取得します self.mergefields = list(set(merges))#TODO:一意にする super(TimeStampedModel、self).save(* args、** kwargs) def __str __(self): return self.wrapper class Meta: ordering =( 'created'、)
シリアライザ
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'])#これは、ResearchオブジェクトのJSONフィールドからのキーの配列でなければなりません class Meta: model = ResearchTemplate fields =( 'id'、 'template')
それらをマッピングする外部キーがあるときにシリアライザーをネストすることができましたが、カスタムクエリセットではそうすることができません。おそらく私はこれについて適切に考えていません。リサーチモデルに何らかの形の「関係」フィールドが必要です。
親モデルから指定された値を持つフィルターから返されるすべての行のシリアル化されたリストをネストするにはどうすればよいですか?
DRFの SerializerMethodField
を使用できます。
ResearchTemplateSerializer
をRelatedField
ではなく、通常のModelSerializerとして定義します。
次に、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