Как отправить POST в modelViewSet, который имеет GenericForeignKey? - PullRequest
0 голосов
/ 03 июля 2018

У меня есть модель, которая использует структуру типов контента django

class Foo(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    content_type = models.ForeignKey(ContentType, on_delete=models.PROTECT)
    object_id = models.UUIDField()
    contentObject = GenericForeignKey()

тогда я использую модель ViewSet и сериализатор

class FooViewSet(viewsets.ModelViewSet):
    serializer_class = FooSerializer
    queryset = Foo.objects.all()

class FooSerializer(serializers.ModelSerializer):
    class Meta:
        model = Foo
        fields = ('__all__')

как я могу создать данные, используя POST для viewSet? Я произвольно попытался POST идентификатор объекта из другой модели на content_type, object_id и content_object, затем я получил ошибку "Неверный тип. Ожидаемое значение pk, получено str."

Я уже смотрю в http://www.django -rest-framework.org / api-guide / relations / # generic-Relations или смотрю переполнение стека, но не могу найти информацию о том, как POST-данные , может быть, мой поиск не был достаточно тщательным, извините. Спасибо за проверку моего вопроса

UPDATE

Я попытался переопределить метод создания в сериализаторе: Я пытаюсь получить объект ContentType из метода get_for_model, но он возвращает AttributeError: у объекта AnotherModelX нет атрибута replace (заменить)

.
def create(self, validated_data):
        content_type =  validated_data.get("object_id")
        taggedObject = AnotherObject1.objects.get(id=content_type) if AnotherObject1.objects.filter(id=content_type).count() > 0 else None
        taggedObject = AnotherObject2.objects.get(id=content_type) if AnotherObject2.objects.filter(id=content_type).count() > 0 and taggedObject == None else None

        if taggedObject is not None:
            contentType = ContentType.objects.get_for_model(taggedObject)
            if contentType is not None:
                validated_data["content_type"] = contentType
                validated_data["object_id"] = taggedObject
        return super(FooSerializer, self).create(validated_data)

class Meta:
    model = Foo
    fields = ('__all__')
    extra_kwargs = {
        'content_type': {'required': False},

1 Ответ

0 голосов
/ 05 июля 2018

Оказывается, мое последнее обновление было близко к решению, это должно быть присвоение идентификатора в validated_data["object_id], тогда это работает. Вот данные POST JSON для Foo:

{
  "object_id": <<another_model_uuid>>
}

Обязательно получите все возможные модели, чтобы taggedObject содержал экземпляр модели.

Теперь это решено, спасибо!

Ниже приведен правильный create метод в сериализаторе

def create(self, validated_data):
        content_type =  validated_data.get("object_id")
        taggedObject = AnotherObject1.objects.get(id=content_type) if AnotherObject1.objects.filter(id=content_type).count() > 0 else None
        taggedObject = AnotherObject2.objects.get(id=content_type) if AnotherObject2.objects.filter(id=content_type).count() > 0 and taggedObject == None else None

        if taggedObject is not None:
            contentType = ContentType.objects.get_for_model(taggedObject)
            if contentType is not None:
                validated_data["content_type"] = contentType
                validated_data["object_id"] = taggedObject.id
        return super(FooSerializer, self).create(validated_data)
...