【问题标题】:Limit the queryset of entries displayed for a django admin Inline限制为 django admin 内联显示的条目的查询集
【发布时间】:2011-10-05 22:17:13
【问题描述】:

在 django admin 中,使用 django 1.2,我正在尝试添加一个 InlineModelAdmin 以在对条目进行更改时对保存应用注释。 (条目的每次编辑都应该有一个“ChangeComment”)。

我不想显示以前的条目,所以我试图通过创建 NoCommentsInlineFormset 并分配我的 ChangeCommentInline 中的表单集,但仍在返回现有条目。

https://docs.djangoproject.com/en/1.3/topics/forms/modelforms/#changing-the-queryset

注意 - 在上面的链接中,他们使用 BaseModelFormset,我使用的是 BaseInlineFormset,我认为这可能是问题所在。如果我将 BaseInlineFormset 换成 BaseModelFormset 我会收到关于“实例”不存在的错误。

admin.py

class NoCommentsInlineFormset(models.BaseInlineFormset):
    def __init__(self, *args, **kwargs):
        super(NoCommentsInlineFormset, self).__init__(*args, **kwargs)
        self.queryset = ChangeComment.objects.none()


class ChangeCommentInline(admin.StackedInline):
    model = ChangeComment
    extra = 1
    exclude = ("user", )
    formset = NoCommentsInlineFormset

    def save_model(self, request, obj, form, change):
        """auto-assign logined in user to comment"""
        if not change:
            obj.user = request.user
        obj.save()    


class EntryAdmin(admin.ModelAdmin):   
    inlines = (ChangeCommentInline, )

可以限制 Inline 中显示的 ChangeComment 条目,还是有更好的方法来处理这个问题?

【问题讨论】:

  • 看看 BaseModelAdmin: def queryset(self, request): """ 返回管理站点可以编辑的所有模型实例的 QuerySet。这由 changelist_view 使用。"""
  • ...您需要做的是覆盖 InlineModelAdmin 上的 queryset 方法。
  • 好的,我试试看。谢谢! (如果您想要更多代表,请继续添加它作为答案)

标签: python django django-admin


【解决方案1】:

正如 benjaoming 在 cmets 中提到的,有必要覆盖 InlineModelAdmin 中的 get_queryset() 方法。没有必要像我最初想的那样覆盖并附加一个新的表单集到 InlineModelAdmin 定义。

这是最终的实现:

class ChangeCommentInline(admin.StackedInline):
    """For allowing logged in user to add change comment"""
    model = ChangeComment
    extra = 1
    exclude = ("user", ) # auto-update user field in save_formset method of parent modeladmin.


    def get_queryset(self, request):
        """Alter the queryset to return no existing entries"""
        # get the existing query set, then empty it.
        qs = super(ChangeCommentInline, self).get_queryset(request)
        return qs.none()  

【讨论】:

  • 应该注意的是,从 Django 1.6 开始,queryset() 方法被称为get_queryset()
  • @GregoryGoltsov 同意:已修复。在 Django 1.6 之前,该方法被称为 queryset()
【解决方案2】:

我假设你正在使用一个

models.ForeignKey(EntryAdmin)

在您的 ChangeComment 模型中。但如果您只想为每个 EntryAdmin 提供一条评论,则应使用:

models.OneToOneField(EntryAdmin)

而且您不需要您的 NoCommentsInlineFormset 或您的内联类。 这就是我会做的。

已编辑

好的,如果你想保留 cmets 的历史,你可以覆盖 NoCommentsInlineFormset 中的查询集 如:

def __init__(self, *args, **kwargs):
    super(NoCommentsInlineFormset, self).__init__(*args, **kwargs)
    self.queryset = ChangeComment.objects.order_by('-created_at')[:1]

这应该可行。

【讨论】:

  • 我正在尝试为给定 ForeignKey 条目的 每个 编辑添加一个“评论”,并维护该评论历史记录。因此,如果进行了 5 次更改,则数据库中将有 5 个 ChangeComment 条目,每次编辑一个。如果我将其更改为 OneToOneField,它不会只允许每个条目一个评论吗?
  • 是的。我认为更简单的解决方案是覆盖表单的查询集并像我在编辑的答案中所做的那样。
  • 我试图覆盖你提到的查询集,但我得到了错误,“查询集”不可调用。原来 InlineModelAdmin 中的查询集 method 需要被覆盖。
猜你喜欢
  • 2013-02-11
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
  • 2016-04-07
  • 2010-12-24
  • 1970-01-01
  • 1970-01-01
  • 2011-03-08
相关资源
最近更新 更多