2015-12-02 4 views
7

Ich habe ein Kontaktformular auf einer Website, die an eine CreateAPIView sendet, um eine neue Instanz eines Modells zu erstellen (das schließlich an den Administrator per E-Mail gesendet wird) . Auf meinem Serializer habe ich ein Honeypot-Feld, um Spam abzuweisen.DRF: Entferne Feld auf Model Serializer nach der Validierung aber vor der Erstellung (auf CreateAPIView)

Das Modell:

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

und Serializer:

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 

und Aussicht:

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

Mein Problem ist, dass, wie es steht, wenn ich zu dieser Ansicht zu veröffentlichen, ich Erhalten Sie den Fehler:

so offensichtlich die seriazlier versucht, das url Feld an das Modell speichern in CreateApiView.perform_create()

versuchte ich read_only zum Serializer Feld hinzufügen, aber dies bedeutet, dass die url_validate Verfahren insgesamt übersprungen.

Wie kann ich das Feld am Serialisierer behalten, bis die Validierung stattgefunden hat, bevor die serializer.save() in perform_create() aufgerufen wird?

Antwort

5

Sie können dies mit dem Verfahren schaffen zwingende wie:

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) 
+0

Ha, ich habe es herausgefunden und geschrieben genau wie Sie. Sie können die Punkte haben;) –

+2

danke für Ihre Antwort, aber 'Message.objects.create (** Daten)' ist falsch, Sie sollten 'valided_data' statt" message.objects.create (** valided_data) "übergeben – shotgunner

0

OK, habe ich den Fehler nicht richtig lesen. Wie es klar sagt:

override the MessageSerializer.create() method to handle this correctly.

Ich suchte die CreateAPIView.create() Methode beim Überschreiben, die keinen Sinn.

Dies funktioniert:

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) 
Verwandte Themen