我有两个模型。其中一个是订阅者
,在保存时我根据已分配给该池的订阅者数量来分配一个池:
class Subscriber(models.Model):
pool = models.ForeignKey(Pool)
interface = models.CharField(max_length=30)
class Pool(models.Model):
name = models.CharField(max_length=50)
假设只有 4 个订阅者
可以分配给一个池。这就是为什么我要重写订阅者的 save()
方法:
def save(self, *args, **kwargs):
if not self.pk:
#Look for a free Pool among the available ones
for pool in Pool.objects.all():
if pool.subscriber_set.count() < 4:
self.pool = pool
print "Assigned pool: %s" % pool.name
super(Subscriber, self).save(*args, **kwargs)
它工作得很好,直到我用完池(所有池都分配了 4 个用户)。我应该如何从 Django 管理员处处理这个问题?理想情况下,我想向用户显示一些错误消息,以便他可以创建更多池。
我不想将池分配代码移至表单的 clean()
方法,因为用户可能也会从不同的界面(而不是管理 GUI)创建。
有什么想法吗?
非常感谢!
最佳答案
我建议在 clean()
和 save()
中进行验证。前者将在管理中为您提供良好的错误消息和工作流程,而后者将确保 save()
本身提供错误消息,无论您如何创建实例。
首先验证:
class Subscriber(models.Model):
def clean(self)
if not self.pk:
if not Pool.objects.annotate(num_subscribers=Count('subscriber'))
.filter(num_subscribers__lt=4)
.exists():
raise ValidationError('The pools are all full.')
这将从管理员自动调用(请参阅 ModelForm
validation 上的文档)。或者 - 如果您不清理 ModelForm
验证之外的内容 - 您可以在表单的 clean()
方法中提供此逻辑。
然后在 save()
方法中执行相同的操作。
def save(self, *args, **kwargs):
if not self.pk:
try:
self.pool = Pool.objects.annotate(num_subscribers=Count('subscriber'))
.filter(num_subscribers__lt=4)[0]
super(Subscriber, self).save(*args, **kwargs)
except IndexError:
raise ValidationError(..)
您可以在 save()
中调用 self.full_clean()
来进行验证,但这个版本似乎更简单(而且肯定更高效)。
关于django - 在 Django Admin 上使用自定义 save() 方法保存模型后返回错误消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23788113/