Как классифицировать ManyToMany по типу поля в Django REST Framework сериализаторе? - PullRequest
0 голосов
/ 03 марта 2020

Не уверен, правильно ли сформулирован заглавный вопрос.

Но в основном вывод JSON настроен так, как я хочу. Мне просто нужно различать каждый тип эффекта в выводе.

В настоящее время он отображает все эффекты для каждого типа эффекта, так как я только что повторил процесс, который я проделал для ароматов, пока выясняю решение.

Любые указания в правильном направлении будут с благодарностью!

models.py

class Effects(models.Model):
    POSITIVE = 'positive'
    NEGATIVE = 'negative'
    MEDICAL = 'medical'
    EFFECTTYPES = [ 
        (POSITIVE, _('Positive')), 
        (NEGATIVE, _('Negative')), 
        (MEDICAL, _('Medical')),
    ]
    name = models.CharField(max_length=255, blank=False)
    etype = models.CharField(max_length=8, choices=EFFECTTYPES, default=POSITIVE, verbose_name="Effect Type")

    class Meta:
        ordering = ['name',]
        verbose_name = _('Effect')
        verbose_name_plural = _('Effects')

    def __str__(self):
        return self.name


class Flavors(models.Model):
    name = models.CharField(max_length=255, blank=False)

    class Meta:
        ordering = ['name',]
        verbose_name = _('Flavor')
        verbose_name_plural = _('Flavors')

    def __str__(self):
        return self.name


class Strain(models.Model):
    name = models.CharField(max_length=255, blank=False)
    INDICA = 'indica'
    SATIVA = 'sativa'
    HYBRID = 'hybrid'
    RACE = [ 
        (INDICA, _('Indica')), 
        (SATIVA, _('Sativa')), 
        (HYBRID, _('Hybrid')),
    ]
    race = models.CharField(max_length=6, choices=RACE, default=INDICA, verbose_name="Race")
    effects = models.ManyToManyField(Effects, blank=False, verbose_name="Effect")
    flavors = models.ManyToManyField(Flavors, blank=False, verbose_name="Flavor")
    desc = models.TextField(blank=True)

    class Meta:
        ordering = ['name',]
        verbose_name = _('Strain')
        verbose_name_plural = _('Strains')

    def __str__(self):
        return self.name

views.py

class StrainViewSet(viewsets.ModelViewSet):
    queryset = Strain.objects.all()
    permission_classes = [
        permissions.AllowAny
    ]
    serializer_class = StrainSerializer

serializer.py

class EffectsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Effects
        fields = ('name', 'etype')

class FlavorsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Flavors
        fields = ('name', )

class StrainSerializer(serializers.ModelSerializer):
    effects = EffectsSerializer(many=True, read_only=True)
    flavors = FlavorsSerializer(many=True, read_only=True)

    class Meta:
        model = Strain
        fields = ('id', 'name', 'race', 'effects', 'flavors', 'desc')

    def to_representation(self, instance):

        def get_flavors_list(self, instance):   
            return list(instance.flavors.values_list('name', flat=True))

        def get_effects_list(self, instance):
            return list(instance.effects.values_list('name', flat=True))

        return {
            instance.name: {
                "id": instance.id,
                "race": instance.race,
                "flavors": get_flavors_list(self, instance),
                "effects": {
                    "positive": get_effects_list(self, instance),
                    "negative": get_effects_list(self, instance),
                    "medical": get_effects_list(self, instance)
                }
            }
        }

ток json выход

{
        "Afpak": {
            "id": 1,
            "race": "hybrid",
            "flavors": [
                "Chemical",
                "Earthy",
                "Pine"
            ],
            "effects": {
                "positive": [
                    "Depression",
                    "Dizzy",
                    "Happy",
                    "Hungry",
                    "Insomnia",
                    "Lack of Apeitite",
                    "Pain",
                    "Relaxed",
                    "Sleepy",
                    "Stress"
                ],
                "negative": [
                    "Depression",
                    "Dizzy",
                    "Happy",
                    "Hungry",
                    "Insomnia",
                    "Lack of Apeitite",
                    "Pain",
                    "Relaxed",
                    "Sleepy",
                    "Stress"
                ],
                "medical": [
                    "Depression",
                    "Dizzy",
                    "Happy",
                    "Hungry",
                    "Insomnia",
                    "Lack of Apeitite",
                    "Pain",
                    "Relaxed",
                    "Sleepy",
                    "Stress"
                ]
            }
        }
    }

требуемый json выход

{
        "Afpak": {
            "id": 1,
            "race": "hybrid",
            "flavors": [
                "Chemical",
                "Earthy",
                "Pine"
            ],
            "effects": {
                "positive": [
                    "Happy",
                    "Hungry",
                    "Relaxed",
                    "Sleepy",
                ],
                "negative": [
                    "Dizzy",
                ],
                "medical": [
                    "Depression",
                    "Insomnia",
                    "Lack of Apeitite",
                    "Pain",
                    "Stress"
                ]
            }
        }
    }

1 Ответ

0 голосов
/ 04 марта 2020

Забыл вернуться сюда раньше, я уже решил это, если кому-то нужно.

Я почти уверен, что есть лучший способ написать это, но сейчас это подойдет.

serializer.py

class StrainSerializer(serializers.ModelSerializer):
    effects = EffectsSerializer(many=True)
    flavors = FlavorsSerializer(many=True)
    positive_types = serializers.SerializerMethodField()
    negative_types = serializers.SerializerMethodField()
    medical_types = serializers.SerializerMethodField()

    class Meta:
        model = Strain
        fields = ('id', 'name', 'race', 'effects', 'flavors', 'desc', 'positive_types', 'negative_types', 'medical_types')

    def to_representation(self, instance):

        def get_flavors_list(self, instance):   
            return list(instance.flavors.values_list('name', flat=True))

        def get_positive_types(self, instance):
            return list(instance.effects.filter(etype='positive').values_list('name', flat=True))

        def get_negative_types(self, instance):
            return list(instance.effects.filter(etype='negative').values_list('name', flat=True))

        def get_medical_types(self, instance):
            return list(instance.effects.filter(etype='medical').values_list('name', flat=True))

        return {
            instance.name: {
                "id": instance.id,
                "race": instance.race,
                "flavors": get_flavors_list(self, instance),
                "effects": {
                    "positive": get_positive_types(self, instance),
                    "negative": get_negative_types(self, instance),
                    "medical": get_medical_types(self, instance)
                },
                "desc": instance.desc
            }
        }
...