Saltar al contenido

Agregar validación de modelo Django personalizada

Solución:

El patrón básico que he encontrado útil es poner toda mi validación personalizada en clean() y luego simplemente llama full_clean() (que llama clean() y algunos otros métodos) desde adentro save(), p.ej:

class BaseModel(models.Model):

    def clean(self, *args, **kwargs):
        # add custom validation here
        super(BaseModel, self).clean(*args, **kwargs)

    def save(self, *args, **kwargs):
        self.full_clean()
        super(BaseModel, self).save(*args, **kwargs)

Esto no se hace de forma predeterminada, como se explica aquí, porque interfiere con ciertas funciones, pero esas no son un problema para mi aplicación.

Yo anularía el validate_unique método en el modelo. Para asegurarse de ignorar el objeto actual al validar, puede utilizar lo siguiente:

from django.db.models import Model, DateTimeField
from django.core.validators import NON_FIELD_ERRORS, ValidationError

class MyModel(Model):
    start_date = DateTimeField()
    end_date = DateTimeField()

    def validate_unique(self, *args, **kwargs):
        super(MyModel, self).validate_unique(*args, **kwargs)

        qs = self.__class__._default_manager.filter(
            start_date__lt=self.end_date,
            end_date__gt=self.start_date
        )

        if not self._state.adding and self.pk is not None:
            qs = qs.exclude(pk=self.pk)

        if qs.exists():
            raise ValidationError({
                NON_FIELD_ERRORS: ['overlapping date range',],
            })

ModelForm lo llamará automáticamente a través de un full_clean(), que también puede utilizar manualmente.

PPR tiene una buena discusión sobre una condición de superposición de rango simple y correcta.

Creo que deberías usar esto: https://docs.djangoproject.com/en/dev/ref/models/instances/#validating-objects

Simplemente defina el método clean () en su modelo de esta manera: (ejemplo del enlace de documentos)

def clean(self):
    from django.core.exceptions import ValidationError
    # Don't allow draft entries to have a pub_date.
    if self.status == 'draft' and self.pub_date is not None:
        raise ValidationError('Draft entries may not have a publication date.')
    # Set the pub_date for published items if it hasn't been set already.
    if self.status == 'published' and self.pub_date is None:
        self.pub_date = datetime.datetime.now()
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *