2015-01-27 18 views
14

Ho un serializzatore che convalida i campi in base ai valori di altri campi, Nella risposta all'errore vorrei mostrare ogni errore di campo come errore di campo come contrario a mostrare tutto sotto "non_field_errors" che è ciò che accadrebbe se dovessi generare un ValidationError nel metodo di validazione a livello di oggetto. Di seguito è riportato un esempio di quello che sto cercando di realizzare:django rest framework: imposta l'errore a livello di campo dal metodo serializer validate()

MySerializer(ModelSerializer): 
    ... 
    def validate(self, data): 
     field_val1 = data['field_val1'] 
     field_val2 = data['field_val2'] 
     if not self._is_field_valid(field_val1, field_val2): 
      # The below line is how I would do what I want with Django 
      # Forms, however, it's not valid in DRF 
      self._errors['field_val1'] = 'this field is not valid' 

La risposta di errore desiderato è:

{'field_val1': ['this field is not valid']} 

risposta

29

ho capito, sulla this pagina della documentazione nella sezione "BaseSerializer" , c'è un esempio che mostra ValidationError può prendere un argomento di dizionario al momento dell'inizializzazione.

Se I raise ValidationError({'field_val1': ['this field is not valid']}) ottengo la risposta JSON desiderata.

+2

Grazie mille per questo. Ho frainteso la fonte e non pensavo che avrebbe funzionato. Questo è esattamente ciò di cui avevo bisogno –

+3

Funziona anche bene per simulare le risposte 'Questo campo è richiesto'. – tyebillion

+0

Non è necessario avvolgere il messaggio di errore nell'elenco. –

1

Analogamente alla risposta da @ Jkk.jonah, questo solleva un ValidationError, ma riutilizza il testo di eccezione originale senza bisogno re-implementare traduzioni:

try: 
    serializer.fields['field_val1'].fail('required') 
except ValidationError as exc: 
    raise ValidationError({ 
     'field_val1': exc.detail, 
    }) 

Per default (cioè sulla rest_framework.fields.Field classe), chiavi disponibili sono:

default_error_messages = { 
    'required': _('This field is required.'), 
    'null': _('This field may not be null.') 
} 

sottoclassi possono aggiungere i loro messaggi di errore proprio lì (e Serializer è una sottoclasse di Field).

BTW, nuovi messaggi di errore saranno automagicamente fusa con esistente (ereditati) messaggi - non verrà sovrascritto come ci si potrebbe aspettare.

0

Se si dispone di logica che si applica a tutti i campi, è ancora possibile ottenere il risultato desiderato in questo modo:

def validate(self, data): 
    for key, value in data.items(): 
     # checks if value is empty 
     if not value: 
      raise serializers.ValidationError({key: "This field should not be left empty."}) 

    return data