Django Поле переименования DRF в сериализаторе, но проверка unique_together не удалась - PullRequest
2 голосов
/ 12 февраля 2020

В сериализаторе, использованном для создания модели, я хочу переименовать поле моей модели в (field_name) _id, чтобы потребителям API было понятнее, что это поле является полем идентификатора. Модель также имеет ограничение unique_together на некоторые поля. Однако, когда в сериализаторе выполняется проверка, происходит сбой с KeyError, что поле не существует:

...rest_framework/utils/serializer_helpers.py", line 148, in __getitem__
    return self.fields[key]
KeyError: 'question'

Есть ли простой способ заставить это работать? Минимальный пример кода ниже.

Модель

class MyModel(Model):
            question = ForeignKey('uppley.Question', null=False, on_delete=PROTECT)
            user = ForeignKey('catalystlab.User', null=False, on_delete=PROTECT)

            class Meta:
                unique_together = ('question', 'user',)

Сериализатор

        class MyCreateSerializer(ModelSerializer):

            question_id = PrimaryKeyRelatedField(
                write_only=True,
                source='question',
                queryset=Question.objects.all(),
            )

            user_id = PrimaryKeyRelatedField(
                write_only=True,
                source='user',
                queryset=User.objects.all(),
            )

            class Meta:
                model = MyModel
                fields = ('question_id', 'user_id',)

test.py - тест для демонстрационных целей

        question = QuestionFactory()
        user = UserFactory()

        data = {
            'question_id': question.id,
            'user_id': user.id,
        }
        serializer = MyCreateSerializer(data=data, write_only=True)
        is_valid = serializer.is_valid(raise_exception=True) #KeyError exception raised here.

Ранее с DRF 3.10.3 все это работало нормально, однако с 3.11.0 теперь выдается KeyError, как упомянуто выше.

То, что я пробовал

Удаление поля source в PrimaryKeyRelatedField для user_id и question_id в сериализаторе фактически приводит к обходу проверки unique_together в DRF, и KeyError избегается. Однако проверенные данные не сопоставляются с исходными именами полей (user и question). В этом случае мы должны вручную изменить ключи на их исходные имена, прежде чем мы сможем создать экземпляр модели из проверенных данных.

Есть ли лучший способ сделать это?

1 Ответ

1 голос
/ 12 февраля 2020

Вы можете создать собственный сериализатор, например: -

class MyCreateSerializer(serializers.Serializer):

    question_id = serializers.PrimaryKeyRelatedField(
         write_only=True,
         queryset=Question.objects.all(),
    )

    user_id = PrimaryKeyRelatedField(
         write_only=True,
         queryset=User.objects.all(),
    )

и создать в нем пользовательскую функцию создания для создания объекта. как: -

def create(self, validated_data):
    try:
        question = validated_data.get('question_id')
        user = validated_data.get('user_id')
        instance = MyModel.objects.create(question=question, user=user)
    except TypeError:
        raise TypeError("Something went wrong while creating objects")

    return instance
...