Mes modèles sont les suivants:
class Question(models.Model): content = models.CharField( max_length=1000, blank=False, default='', ) def __str__(self): return self.content class OptionGroup(models.Model): question = models.ForeignKey( 'Question', on_delete=models.CASCADE, default='', ) options = models.ManyToManyField('Option') class Option(models.Model): content = models.CharField( max_length=1000, blank=False, default='', )
J'essaye de créer un sérialiseur de question qui sérialisera Question.content et tout le Option.content associé sans afficher aucun champ d'OptionGroup. Comment faire cela?
3 Réponses :
Vous pouvez sérialiser des modèles associés en utilisant des sérialiseurs imbriqués comme celui-ci:
{ 'content': 'some content', # your Question 'options': [ {'content': 'some content'}, # related Option {'content': 'some other content'}, # related Option ... ], }
Ce qui donnera le résultat suivant:
class OptionSerializer(serializers.ModelSerializer): class Meta: model = Option fields = ('content',) class QuestionSerializer(serializers.ModelSerializer): options = OptionSerializer(many=True, read_only=True) class Meta: model = Question fields = ('content', 'options')
Vous pouvez Pour en savoir plus sur les sérialiseurs imbriqués, cliquez ici .
p>
Avez-vous vu la structure du modèle? L'option n'est pas directement liée à la question. Ça ne marche pas pour moi comme ça.
modèles:
class OptionSerializer(serializers.ModelSerializer): class Meta: model = Option exclude = ('id',) class QuestionSerializer(serializers.ModelSerializer): options = serializers.SerializerMethodField(read_only=True) def get_options(self, obj): options = obj.get_options() return OptionSerializer(options, many=True).data class Meta: model = Question fields = "__all__"
sérialiseurs
class OptionGroup(models.Model): question = models.ForeignKey( 'Question', on_delete=models.CASCADE, default='', related_name='question_options' ) options = models.ManyToManyField('Option') class Question(models.Model): content = models.CharField( max_length=1000, blank=False, default='', ) # options = models.ManyToManyField('Option', through='OptionGroup') def get_options(self): options = self.question_options.all().values('options') option_ids = [] for option in options: option_ids.append(option['options']) return Option.objects.filter(id__in=option_ids) def __str__(self): return self.content class Option(models.Model): content = models.CharField( max_length=1000, blank=False, default='', ) def __str__(self): return self.content
Beaucoup d'erreurs dans votre réponse. Vous avez déclaré OptionSerializer
mais ne l'avez pas utilisé. Vous utilisez un champ question_options
mais il n'est pas défini sur ce modèle particulier (en supposant que vous vouliez dire optiongroup_set
). Mais toujours après avoir corrigé ceux-ci, ce n'est toujours pas dans le format que je souhaite. Le format que je veux est ce que @Stevy a donné ci-dessus mais sa réponse est également fausse car l'option n'est pas directement liée à la question.
Créez un champ SerializerMethod et définissez-le en conséquence:
serializers.py
from rest_framework import serializers from diagnosisApp.models import Question, Option class OptionSerializer(serializers.ModelSerializer): class Meta: model = Option fields = ('id', 'content') class QuestionSerializer(serializers.ModelSerializer): options = serializers.SerializerMethodField() class Meta: model = Question fields = ('content', 'options') def get_options(self, obj): selected_options = Option.objects.filter( optiongroup__question=obj).distinct() return OptionSerializer(selected_options, many=True).data
pourquoi vous utilisez OptionGroup? vous pouvez mettre des options dans le modèle
Question
Il existe d'autres champs sur OptionGroup que j'ai omis par souci de simplicité.