假设我正在编写一个多博客应用程序,并且我希望每个作者为其文章使用唯一的标题(但每个用户都是唯一的,而不是全球唯一的):
class Article(models.Model):
author = models.ForeignKey('auth.User')
title = models.CharField(max_length=255)
#[...]
class Meta:
unique_together = (('title', 'owner'),)
现在,我希望应用程序自动填充作者字段:
class ArticleAdmin(ModelAdmin):
exclude = ('owner',)
def save_model(self, request, obj, form, change):
if not change:
obj.owner = request.user
obj.save()
实际上这不起作用:如果我尝试使用现有的作者-标题组合创建一个新文章,Django 将不会检查唯一性(因为作者被排除在表单之外)并且当它到达数据库时我会得到一个 IntegrityError。
我想在 Article 类中添加一个干净的方法:
def clean(self):
if Article.objects.filter(title=self.title, owner=self.owner).exists():
raise ValidationError(u"...")
但似乎在 ArticleAdmin.save_model()之前调用了Article.clean(),所以这不起作用。
这里已经提出了这个问题的几个变体,但似乎没有一个解决方案对我有用:
- 我不能使用 Form.clean() 或其他没有可用请求的表单方法,因为我需要 request.user。
- 出于同样的原因,模型级别的验证是不可能的。
- 一些答案是指基于类的视图或自定义视图,但我想留在 Django 管理员的上下文中。
有什么想法可以在不重写一半管理应用程序的情况下做到这一点吗?