2012-03-07 14 views
8

¿Cómo puedo asegurar que se establezca al menos una relación de muchos a muchos?Modelos de Django: al menos uno en muchos o muchos

Por ejemplo: Si tengo un modelo listing que tiene un campo de imagencon una relación de muchos a muchos a images. ¿Cómo puedo asegurarme de que al menos una imagen está configurada?

Pregunta de bonificación: ¿Qué pasa si el mínimo es algo distinto de uno? ¿Qué tal un máximo?

+3

¿Qué quiere decir con asegurar? ¿Evitar guardar a menos que haya la cantidad requerida de imágenes? –

+0

Sí, asegurándose de que al menos uno esté presente (y si es posible también tenga un máximo) – RS7

+0

¿Lo necesita filtrar listados o en otro lugar? Mientras filtra, puede usar la anotación y filtrar por número resultante. – ilvar

Respuesta

3

Se puede implementar una función para comprobar si la instancia Listing tiene al menos una instancia de imagen y conectar esa función para el modelo Listingpre_save signal

Va a ser algo así como: (suponiendo que está utilizando Django 1.3)

from django.db.models.signals import pre_save 
from django.dispatch import receiver 
from myapp.models import Listing 
... 
@receiver(pre_save, sender=Listing) 
def check_image_requirement(sender, instance, **kwargs): 
    if instance.images.count() == 0: 
     raise your_own_exception("Listing is required to have at least one image") 

donde es necesario implementar your_own_exception

la siguiente adición es la respuesta a otra pregunta del PO

La implementación de Listing.clean() es otra forma de lograr la misma regla de validación. De hecho, es el enfoque semánticamente correcto, ya que Model.clean() está diseñado para validaciones de modelos personalizados. Pero adoptar este enfoque sería menos conveniente: para activar el clean(), debe llamar manualmente al full_clean() (si no usa el formulario del modelo) o llamar manualmente al is_valid() (cuando usa el modelo), justo antes de llamar al save() de un Listado ejemplo. Reference

Por otro lado, con el enfoque pre_save señal, puede estar seguro de que la regla de validación se aplica siempre en Listing ejemplo, cada vez que llame save() en la instancia.

No es correcto o incorrecto elegir uno sobre el otro, sino simplemente una decisión de diseño para hacer. Ambos enfoques pueden lograr lo que necesita y mantener la lógica de negocio/dominio (es decir, su regla de validación) en la capa Modelos.

+0

I' Soy bastante nuevo para phython/django. ¿Pre_save se ejecutó antes de la validación del campo (antes de asegurarse, por ejemplo, de que un campo entero sea entero, o que una restricción de clave externa coincida)? ¿Por qué pre_save y no clean()? Al usar un comando clean(), ¿estoy sobreescribiendo la validación del campo o extendiéndola? ¡Gracias por la ayuda! – RS7

+0

@ RS7 - Sin preocupaciones. Todos están aquí para aprender, incluyéndome a mí. He agregado mi respuesta en respuesta a sus preguntas adicionales. – tamakisquare

+0

Gracias, muy informativo - última pregunta: ¿Qué pasa si el modelo 'listing' tenía muchas imágenes representadas por el modelo' image'. Si entendiera los documentos correctamente, en lugar de muchas 'imágenes' de campo, crearía un modelo diferente, ¿sí? Entonces, para verificar si se cumple el mínimo, ¿accedería de la misma manera? 'self.image.count()' si lo estaba haciendo en 'clean()'? – RS7

Cuestiones relacionadas