If I have a model with a ManyToManyField
and I want to restrict it to instances that have a particular property, what's the best way to do this? I can do it in the form validation or in the view, but I'd like to do it closer to the model.
如果我有一个带有ManyToManyField的模型,并且我想将它限制为具有特定属性的实例,那么最好的方法是什么?我可以在表单验证或视图中执行此操作,但我希望更接近模型。
For example, how can I only allow instances of class B that have is_cool set to True to be associated with class A instances?
例如,我怎样才能只允许将is_cool设置为True的B类实例与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)
1 个解决方案
#1
1
To be closer to the model, you can use the m2m_changed signal to check if the model matches your requirements, so the code could look like this:
为了更接近模型,您可以使用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)
#1
1
To be closer to the model, you can use the m2m_changed signal to check if the model matches your requirements, so the code could look like this:
为了更接近模型,您可以使用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)