DRF: удалить поле в сериализаторе модели после проверки, но перед созданием (в CreateAPIView)

У меня есть контактная форма на сайте, который публикует в CreateAPIView, чтобы создать новый экземпляр модели (который в конечном итоге по электронной почте администратору). На моем сериализаторе у меня есть поле honeypot, чтобы помочь отклонить спам.

Модель:

class Message(models.Model):
    name = ...
    message = ...

и сериализатор:

class MessageSerializer(serializers.ModelSerializer):

    # Honeypot field
    url = serializers.CharField(allow_blank=True, required=False)

    class Meta:
        model = Message
        fields = '__all__'

    def validate_url(self, value):
        if value and len(value) > 0:
            raise serializers.ValidationError('Spam')
        return value

и просмотр:

class MessageView(generics.CreateAPIView):
    ''' Create a new contact form message. '''
    serializer_class = MessageSerializer

Моя проблема в том, что при публикации в этом представлении я получаю сообщение об ошибке:

  

TypeError: Получил TypeError при вызове Message.objects.create()

очевидно, что сериализатор пытается сохранить поле url в модели в CreateApiView.perform_create()

Я попытался добавить read_only в поле сериализатора, но это означает, что url_validate вообще пропускается.

Как сохранить поле в сериализаторе до тех пор, пока не произойдет проверка, удалив его до вызова serializer.save() в perform_create()

7 голосов | спросил Timmy O'Mahony 2 WedEurope/Moscow2015-12-02T21:48:21+03:00Europe/Moscow12bEurope/MoscowWed, 02 Dec 2015 21:48:21 +0300 2015, 21:48:21

2 ответа


0

вы можете сделать это, переопределив метод create, например:

class MessageSerializer(serializers.ModelSerializer):

    # Honeypot field
    url = serializers.CharField(allow_blank=True, required=False)

    class Meta:
        model = Message
        fields = '__all__'

    def validate_url(self, value):
        if value and len(value) > 0:
            raise serializers.ValidationError('Spam')
        return value

    def create(self, validated_data):
        data = validated_data.pop('url')
        return Message.objects.create(**data)
ответил Anush Devendra 2 WedEurope/Moscow2015-12-02T21:56:17+03:00Europe/Moscow12bEurope/MoscowWed, 02 Dec 2015 21:56:17 +0300 2015, 21:56:17
0

Хорошо, я не правильно прочитал ошибку. Как ясно сказано:

  

переопределите метод MessageSerializer.create () для правильной обработки.

Я пытался переписать метод CreateAPIView.create(), который не имел смысла.

Это работает:

class MessageSerializer(serializers.ModelSerializer):

    # Honeypot field
    url = serializers.CharField(allow_blank=True, required=False)

    class Meta:
        model = Message
        fields = '__all__'

    def validate_url(self, value):

        if value and len(value) > 0:
            raise serializers.ValidationError('Error')
        return value

    def create(self, validated_data):
        if "url" in validated_data:
            del validated_data["url"]
        return Message.objects.create(**validated_data)
ответил Timmy O'Mahony 2 WedEurope/Moscow2015-12-02T21:56:40+03:00Europe/Moscow12bEurope/MoscowWed, 02 Dec 2015 21:56:40 +0300 2015, 21:56:40

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132