Django REST Framework Ошибка ManyToMany - PullRequest
0 голосов
/ 05 мая 2018

Когда я добавляю сериализатор для поля ManyToMany, он отображает результаты в REST API, но когда я публикую данные, тогда сериализатор дает is_valid () как false. Когда я упоминаю их как JSONFields, тогда сериализатор is_valid () имеет значение True и данные сохраняются, но при просмотре API на localhost выдает следующую ошибку: «Объект типа« ManyRelatedManager »не является сериализуемым JSON»

class B(models.model):
    name = models.CharField()

class A(models.model):
    b = models.ManyToManyField(B)

class BSerializer(serializer.modelSerializer):
    class Meta:
        model=B
        fields = '__all__'

class ASerializer(serializer.ModelSerializer):
    b = BSerializer(many=true)

    def save(self):
        b_data = self.validated_data.pop('b')
        a = A.objects.create(**validated_data)
        b_instance = B.objects.get(name=b_data['name'])
        a.add(b_instance)

Это дает отличные результаты в пользовательском интерфейсе REST Framework при нажатии http://localhost:8000/a/REST, но когда я нажимаю запрос POST для почтальона с данными {'b': [{'name': 'foo'}]} Сериализатору не удается выполнить функцию is_valid ().

Но когда я изменяю код на это:

class ASerializer(serializer.ModelSerializer):
    b = serializer.JSONField()

    def save(self):
        b_data = self.validated_data.pop('b')
        a = A.objects.create(**validated_data)
        b_instance = B.objects.get(name=b_data['name'])
        a.add(b_instance)

Хит почтальона сохраняет данные для A, а затем добавляет к нему экземпляр b. Это видно, когда я вижу данные в оболочке Python. Но при просмотре в пользовательском интерфейсе REST Framework выдается следующая ошибка: 'Объект типа' ManyRelatedManager 'не поддерживает сериализацию в формате JSON'

Ответы [ 2 ]

0 голосов
/ 06 мая 2018

Как ответил @Satendra, я сделал 2 сериализатора, но получил ошибки в viewset.

def create(self, request):
    try:
        serializer = self.get_serializer_class()
        if serializer.is_valid():
            serializer.save()
            return Response({"status": "success"})
        else:
            return Response({"status": "failure", "reason": 'Serializer not valid'})
    except Exception as e:
        print('Error in viewset', e)
        return Response({"status": "failure", "reason": e})

Так что просто изменили этот код и добавили новую строку, создающую экземпляр сериализатора с данными после вызова get_serializer_class, и он отлично работает как для запросов get, так и для post и с использованием отдельных сериализаторов для get и post

serializer = serializer(data=self.request.data)
0 голосов
/ 05 мая 2018

Вы должны создать два отдельных сериализатора

один для поиска.

class A_RetriveSerializer(serializer.ModelSerializer):
    b = BSerializer(many=true)

    class Meta:
       model = A
       fields = '__all__'

и др. Для создания объекта.

class A_PostSerializer(serializer.ModelSerializer):
    b = serializer.JSONField()

    class Meta:
       model = A
       fields = ('b', )

    def save(self):
        b_data = self.validated_data.pop('b')
        a = A.objects.create(**validated_data)
        b_instance = B.objects.get(name=b_data['name'])
        a.b.add(b_instance)

и, по вашему мнению, переопределить get_serializer_class метод

def get_serializer_class(self):
    if self.request.method == 'POST':
       return A_PostSerializer
    return A_RetriveSerializer
...