2013-11-25 10 views
7

Ich versuche, die maximale Anzahl von Auswahlmöglichkeiten zu begrenzen, die ein Modell-Datensatz in einem ManyToManyField haben kann.Limit Maximum Choices von ManyToManyField

In diesem Beispiel gibt es eine BlogSite, die sich auf Regionen beziehen kann. In diesem Beispiel möchte ich die BlogSite beschränken, um nur 3 Regionen zu haben.

Das scheint etwas zu sein, das vorher gefragt/beantwortet worden wäre, aber nach ein paar Stunden Stochern konnte ich nichts in der Nähe finden. Für dieses Projekt verwende ich Django 1.3.

#models.py 
class BlogSite(models.Model): 
    blog_owner = models.ForeignKey(User) 
    site_name = models.CharField(max_length=300) 
    region = models.ManyToManyField('Region', blank=True, null=True) 
    .... 

class Region(models.Model): 
    value = models.CharField(max_length=50) 
    display_value = models.CharField(max_length=60) 
    .... 

Irgendwelche Ideen?

Antwort

10

können Sie außer Kraft setzen clean Methode auf Ihrem BlogSite Modell

from django.core.exceptions import ValidationError 

class BlogSite(models.Model): 

    blog_owner = models.ForeignKey(User) 
    site_name = models.CharField(max_length=300) 
    regions = models.ManyToManyField('Region', blank=True, null=True) 

    def clean(self, *args, **kwargs): 
     if self.regions.count() > 3: 
      raise ValidationError("You can't assign more than three regions") 
     super(BlogSite, self).clean(*args, **kwargs) 
     #This will not work cause m2m fields are saved after the model is saved 

Und wenn Sie Djangos Modelform verwenden, dann wird dieser Fehler in Form des non_field_errors erscheinen.

EDIT:

M2m Felder werden nach dem Modell gespeichert gespeichert wird, so dass der Code über die richtige Art und Weise nicht funktioniert, Sie m2m_changed Signal verwenden können:

from django.db.models.signals import m2m_changed 
from django.core.exceptions import ValidationError 


def regions_changed(sender, **kwargs): 
    if kwargs['instance'].regions.count() > 3: 
     raise ValidationError("You can't assign more than three regions") 


m2m_changed.connect(regions_changed, sender=BlogSite.regions.through) 

Probieren Sie es selbst es funktionierte für mich.

+0

Das ist sehr nah. Aus irgendeinem Grund erlaubt dies mir, mehr als 3 Regionen zu speichern, aber wenn ich versuche, danach zu speichern, um auf 2 zu korrigieren, gibt es mir den Fehler. Arbeiten an einer Lösung von hier, danke ... – awwester

+0

Ich aktualisierte meine Antwort. – Mounir

+0

die Bearbeitung funktioniert. Gut zu wissen über den sauberen Unterschied für m2m, danke! – awwester

0

Das Beste, was mir einfällt, ist, ein Vorabrufsignal für BlogSite zu haben und zu prüfen, ob diese Instanz von BlogSite bereits 3 Regionen hat.

@receiver(pre_save, sender=BlogSite) 
def check_regions_limit(sender, instance, **kwargs): 
    if instance.regions.count() == 3: 
     raise_some_exception("Can't add more than 3 regions to a BlogSite") 
+2

Diese Antwort ist falsch. 'pre_save' wird gefeuert, wenn die m2m-Speicherung noch nicht erfolgt ist, so dass die Zählung den Wert vor der Änderung zurückgibt. – andi