Django管理列表显示设置的替代代码位置

时间:2013-11-21 10:26:30

标签: python django

我正在遵循Django 1.6的教程,其中包含一个模型Poll,它具有派生属性was_published_recentlyclass Poll的方法)。该模型最初定义如下。

# polls/models.py (excerpted)

class Poll(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

此应用的管理界面:

# polls/admin.py (excerpted)

class PollAdmin(admin.ModelAdmin):
    # ...
    list_display = ('question', 'pub_date', 'was_published_recently')

admin.site.register(Poll, PollAdmin)

现在我们想要改进was_published_recently的显示和排序功能。

在教程中,文件polls/models.py已更新:

class Poll(models.Model):
    # ...
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'

但是,我认为这在实践中可能不够好,因为我们指定的完全是关于管理员用户界面,而不是模型本身。所以我更新了polls/admin.py

class PollAdmin(admin.ModelAdmin):
    Poll.was_published_recently.admin_order_field = 'pub_date'
    Poll.was_published_recently.boolean = True
    Poll.was_published_recently.short_description = 'Published recently?'
    # ...

在此修改之后,应用程序也按预期工作(多个民意调查也很有效)。由于我是Python的新手,我通过在was_published_recentlyPoll中打印PollAdmin来进一步调查:

class Poll(models.Model):
    # ...
    print("in class Poll", was_published_recently)

class PollAdmin(admin.ModelAdmin):
    print("in class PollAdmin", Poll.was_published_recently)
    # ...

输出

in class Poll <function Poll.was_published_recently at 0x10fc92050>
in class PollAdmin <function Poll.was_published_recently at 0x10fc92050>

was_published_recently显然class PollPoll.published_recently中访问的class PollAdmin相同。

我的问题:我应该在admin_order_fieldadmin.py中指定models.py内容吗?如果在admin.py而不是models.py中指定,是否有任何缺点?

1 个答案:

答案 0 :(得分:2)

简而言之,一切都按预期工作,在admin_order_fieldmodels.py中放置admin.py内容在语义上相同。

  

显然,在Poll类中,was_published_recently与在PollAdmin类中访问的Poll.published_recently相同。

是。它们应该是一样的。类是对象。所以Poll是一个对象。 Poll.was_published_recently是对象Poll的属性,也是类型为instancemethod的对象。无论您在何处访问它,它都是同一个对象。

AFAIK,在admin_order_fieldmodels.py中撰写admin.py内容的唯一区别是解释顺序。 Django在models.py之前加载admin.py,所以一切都在加载时运行并且依赖于admin_order_field的东西将会失败。但由于admin_order_field仅用于admin.py,我认为你所做的很好。

Python是如此动态,允许您甚至从其他模块修改定义。这可能导致难以发现的错误和糟糕的可读性/可维护性。请务必谨慎使用这种黑魔法。