2013-11-25 24 views
7

Bir model kaydının bir ManyToManyField içinde sahip olabileceği en fazla seçenek miktarını sınırlamaya çalışıyorum.ManyToManyField Sınır Değerleri Sınırı

Bu örnekte Bölgeler ile ilgili olabilecek bir BlogSitesi var. Bu örnekte, yalnızca 3 bölgeye sahip olmak için BlogSite'ı sınırlamak istiyorum.

Bu, daha önce sorulmuş/cevaplanmış bir şey gibi görünüyor, ama etrafta birkaç saat uğraştıktan sonra yakın bir şey bulamadım. Bu proje için Django 1.3 kullanıyorum.

#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) 
    .... 

Herhangi bir fikir?

cevap

10

Sen BlogSite modeline

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 

üzerinde clean yöntemi geçersiz kılabilirsiniz Ve Django'nın ModelForm kullanırsanız o zaman bu hata formun non_field_errors görünecektir.

DÜZENLEME:

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) 

bir işe yaradı deneyin ver: kaydedildiği Yukarıdaki kod çalışmaz böylece

M2m alanları, modelin sonra m2m_changed sinyalini kullanabilirsiniz doğru yolu kaydedilir benim için.

+0

Bu çok yakın. Bazı nedenlerden ötürü bu, 3'ten fazla bölgeyi kaydetmeme izin veriyor, ancak sonra 2'ye kadar düzeltmek için bundan sonra kaydetmeye çalıştığımda bana hata veriyor. Buradan bir çözüm üzerinde çalışıyorum, teşekkürler ... – awwester

+0

Cevabımı güncelledim. – Mounir

+0

düzenleme işleri. M2m için temiz fark hakkında bilmek iyi, teşekkürler! – awwester

0

Düşünebildiğim en iyi şey BlogSite için önceden kaydedilen bir sinyale sahip olmak ve bu BlogSite örneğinin 3 bölgeye sahip olup olmadığını kontrol etmektir.

@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

Bu cevap YANLIŞ. m2m kaydetme henüz gerçekleşmediğinde 'pre_save' tetiklenir, böylece sayım değişmeden önce değeri döndürür. – andi