Django模型 - 至少有一对多

时间:2022-10-04 14:10:55

How can I ensure that at least one many to many relation is set?

如何确保至少设置多对多关系?

For example: If I have a listing model which has a image field with a many to many relation to images. How can I ensure that at least one image is set

例如:如果我有一个列表模型,其具有与图像有多对多关系的图像字段。如何确保至少设置一个图像

Bonus question: What if the minimum was something other than one? What about a maximum?

奖金问题:如果最低限度不是一个,该怎么办?最大值怎么样?

1 个解决方案

#1


3  

You can implement a function to check if the Listing instance has at least one image instance, and connect that function to the Listing model's pre_save signal

您可以实现一个函数来检查Listing实例是否至少有一个图像实例,并将该函数连接到Listing模型的pre_save信号

It'll be something like, (assuming you are using django 1.3)

它会是这样的(假设你正在使用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")

where you need to implement your_own_exception

你需要在哪里实现your_own_exception

The following addition is the response to PO's further questions

以下补充是对PO的进一步问题的回应

Implementing Listing.clean() is another way to achieve the same validation rule. Indeed, it's the semantically correct approach as Model.clean() is meant for custom model validations. But adopting this approach would be less convenient - to trigger the clean() you would have to either manually call full_clean() (if you don't use model form), or manually call is_valid() (when using model form), right before calling save() of a Listing instance. Reference

实现Listing.clean()是实现相同验证规则的另一种方法。实际上,它是语义上正确的方法,因为Model.clean()用于自定义模型验证。但采用这种方法不太方便 - 触发clean()你必须手动调用full_clean()(如果你不使用模型形式),或者手动调用is_valid()(当使用模型表单时),在调用Listing实例的save()之前。参考

On the other hand, with the pre_save signal approach, you can be certain that the validation rule is always applied on Listing instance whenever you call save() on the instance.

另一方面,使用pre_save信号方法,您可以确定每当您在实例上调用save()时,验证规则始终应用于Listing实例。

It's not a right-or-wrong to choose one over the other but merely a design decision to make. Both approaches can achieve what you need and keep the business/domain logic (ie. your validation rule) in the Models layer.

选择一个而不是另一个而不仅仅是做出设计决定并不是对错。这两种方法都可以实现您的需求,并在Models层中保留业务/域逻辑(即您的验证规则)。

#1


3  

You can implement a function to check if the Listing instance has at least one image instance, and connect that function to the Listing model's pre_save signal

您可以实现一个函数来检查Listing实例是否至少有一个图像实例,并将该函数连接到Listing模型的pre_save信号

It'll be something like, (assuming you are using django 1.3)

它会是这样的(假设你正在使用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")

where you need to implement your_own_exception

你需要在哪里实现your_own_exception

The following addition is the response to PO's further questions

以下补充是对PO的进一步问题的回应

Implementing Listing.clean() is another way to achieve the same validation rule. Indeed, it's the semantically correct approach as Model.clean() is meant for custom model validations. But adopting this approach would be less convenient - to trigger the clean() you would have to either manually call full_clean() (if you don't use model form), or manually call is_valid() (when using model form), right before calling save() of a Listing instance. Reference

实现Listing.clean()是实现相同验证规则的另一种方法。实际上,它是语义上正确的方法,因为Model.clean()用于自定义模型验证。但采用这种方法不太方便 - 触发clean()你必须手动调用full_clean()(如果你不使用模型形式),或者手动调用is_valid()(当使用模型表单时),在调用Listing实例的save()之前。参考

On the other hand, with the pre_save signal approach, you can be certain that the validation rule is always applied on Listing instance whenever you call save() on the instance.

另一方面,使用pre_save信号方法,您可以确定每当您在实例上调用save()时,验证规则始终应用于Listing实例。

It's not a right-or-wrong to choose one over the other but merely a design decision to make. Both approaches can achieve what you need and keep the business/domain logic (ie. your validation rule) in the Models layer.

选择一个而不是另一个而不仅仅是做出设计决定并不是对错。这两种方法都可以实现您的需求,并在Models层中保留业务/域逻辑(即您的验证规则)。