Sto ancora cercando di capire il modo corretto per convalidare un oggetto modello Django usando un validatore personalizzato a livello di modello. So che la convalida viene solitamente eseguita all'interno di una forma o di un modello. Tuttavia, voglio garantire l'integrità dei miei dati a livello di modello se sto interagendo con l'ORM nella shell Python. Ecco il mio approccio attuale:Modo corretto per convalidare gli oggetti del modello Django?
from django.db import models
from django.core import validators
from django.core exceptions import ValidationError
def validate_gender(value):
""" Custom validator """
if not value in ('m', 'f', 'M', 'F'):
raise ValidationError(u'%s is not a valid value for gender.' % value)
class Person(models.Model):
name = models.CharField(max_length=128)
age = models.IntegerField()
gender = models.CharField(maxlength=1, validators=[validate_gender])
def save(self, *args, **kwargs):
""" Override Person's save """
self.full_clean(exclude=None)
super(Person, self).save(*args, **kwargs)
Ecco le mie domande:
Devo creare una funzione di validazione personalizzata, designare come un validatore, e quindi sovrascrivere della persona save() funzionano come I' hai fatto sopra? (A proposito, so che potrei convalidare le mie scelte di genere usando l'opzione di campo 'scelte' ma ho creato 'validate_gender' a scopo illustrativo).
Se davvero voglia di garantire l'integrità dei dati, dovrei non solo scrivere unit test Django per i test a livello di modello, ma anche test di unità equivalenti a livello di database utilizzando Python/psycopg? Ho notato che i test delle unità Django, che aumentano ValidationErrors, testano solo la comprensione del modello dello schema del database utilizzando una copia del database. Anche se dovessi usare South per le migrazioni, tutti i vincoli a livello di database sono limitati a ciò che Django può capire e tradurre in un vincolo di Postgres. Se ho bisogno di un vincolo personalizzato che Django non può replicare, potrei potenzialmente inserire dati nel mio database che violano tale vincolo se sto interagendo con il database direttamente tramite il terminale psql.
Grazie!
Non sono sicuro di come la domanda 1 sia diversa dalle precedenti domande su questo argomento. Si noti che non impedisce ancora l'inserimento di dati non validi utilizzando l'ORM. Si consideri 'Person.objects.update (gender = 'a')'. – Alasdair
Sei corretto tranne che nella mia precedente domanda non ho incluso una funzione di validazione personalizzata come ho fatto qui. Per quanto riguarda la tua altra osservazione su. Aggiornamento, credo che ora ho un ulteriore problema che aggiunge alla mia confusione.Sto davvero lottando per capire qual è il modo giusto per farlo. Mentre i documenti di Django sono piuttosto buoni, IMHO, sono lunghi su frammenti e "mani che salutano", ma su esempi completi che potrebbero aiutare un "newb" come me a capire il modo corretto per risolvere questo problema. Sfortunatamente, lavoro da solo e non ho sviluppatori più esperti con cui discutere. – William