假设我正在编写一个多博客应用程序,我希望每个作者都能为他们的文章使用独特的标题(但每个用户都是唯一的,而不是全球唯一的):
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"...")
但似乎Article.clean()在 ArticleAdmin.save_model()之前被称为,所以这不起作用。
这个问题的Several variants已经在这里提出过,但是没有一个解决方案对我有用:
如果不重写一半管理应用程序,我怎么能这样做呢?
答案 0 :(得分:0)
您正在寻找一种方法将request
带到ModelAdmin的自定义表单中,实际上是:
from django.core.exceptions import ValidationError
def make_add_form(request, base_form):
class ArticleForm(base_form):
def clean(self):
if Article.objects.filter(title=self.cleaned_data['title'], owner=request.user).exists():
raise ValidationError(u"...")
return self.cleaned_data
def save(self, commit=False):
self.instance.owner = request.user
return super(ArticleForm, self).save(commit=commit)
return ArticleForm
class ArticleAdmin(admin.ModelAdmin):
exclude = ('owner',)
def get_form(self, request, obj=None, **kwargs):
if obj is None: # add
kwargs['form'] = make_add_form(request, self.form)
return super(ArticleAdmin, self).get_form(request, obj, **kwargs)