2012-07-01 51 views
1

如果我有一个ManyToManyField的模型,并且我想将它限制为具有特定属性的实例,那么执行此操作的最佳方法是什么?我可以在表单验证中或在视图中执行此操作,但我希望更接近模型。什么是验证ManyToManyFields的正确方法?

例如,我如何才允许将class_B的is_cool设置为True的实例与类A实例关联?

from django.db import models 

class A(models.Model): 
    cool_bees = models.models.ManyToManyField('B') 

class B(models.Model): 
    is_cool = models.BooleanField(default=False) 
+0

@okm真是没有,你拿走了我的麦康奈尔空间!不要试图拉我的PEP 8,因为它没有提到关于定义的任何内容,只是关于函数调用。 ;) – aptwebapps

回答

1

更接近模型,你可以使用m2m_changed信号,以检查是否符合模型的要求,所以代码看起来是这样的:

import django.db.models.signals 

def validate(sender, instance, action, reverse, model, pk_set, **kwargs): 
    if action == "pre_add": 
     # if we're adding some A's that're not cool - a.cool_bees.add(b) 
     if not reverse and model.objects.filter(pk__in=pk_set, is_cool=False): 
       raise ValidationError("You're adding an B that is not cool") 
     # or if we add using the reverse - b.A_set.add(a) 
     if reverse and not instance.is_cool: 
       raise ValidationError("You cannot insert this non-cool B to A") 


signals.m2m_changed.connect(validate, sender=A.cool_bees.through) 
+0

谢谢。有没有办法与模型验证做到这一点?如果我在这里提出'ValidationError',我只需要自己去捕捉它。这并不是那么困难,但我希望把事情放在一个地方。 – aptwebapps

+0

m2m更改不在model.save中执行,因此很难在模型验证中添加它们。但是,您可以设置模型属性,例如a.is_valid而不是引发ValidationError并跳过错误的项目,然后稍后在模型验证中检查它,但这样可能会隐藏一些错误... – Tisho

相关问题