5

我刚刚开始使用 Django 管理视图,开始时,我正在尝试做一些非常简单的事情:使用 list_display 在对象列表中显示几个字段,如下所述:https ://docs.djangoproject.com/ en/dev/ref/contrib/admin/

这是我死的简单代码:

class ArticleAdmin(admin.ModelAdmin):
     list_display = ('title', 'category')

不幸的是,list_display 选项导致出现柱状视图,但现在只有一些对象(85 个中的 40 个)显示在列表中。我无法推断为什么某些对象会显示在其他对象之上——它们的字段看起来像是被类似填充的。它显然没有分页,因为当我在另一个模型的管理员上尝试它时,它只显示了大约 70 个对象中的 2 个对象。

这里可能发生了什么?

[更新]文章模型:

class Article(models.Model):
    revision = models.ForeignKey('ArticleRevision', related_name="current_revision")
    category = models.ForeignKey('meta.Category')
    language = models.ForeignKey('meta.Language', default=get_default_language)
    created = models.DateTimeField(auto_now_add=True, editable=False)
    changed = models.DateTimeField(auto_now=True, editable=False)
    title = models.CharField(max_length=256)
    resources = models.ManyToManyField('oer.Resource', blank=True)
    image = models.ManyToManyField('media.Image', blank=True)
    views = models.IntegerField(editable=False, default=0)
    license = models.ForeignKey('license.License', default=get_default_license)
    slug = models.SlugField(max_length=256)
    difficulty = models.PositiveIntegerField(editable=True, default=0)
    published = models.NullBooleanField()
    citation = models.CharField(max_length=1024, blank=True, null=True)

添加 list_display 之前:

list_display 之前的 Django amdin

添加 list_display 后:

list_display 之后的 Django amdin

[更新]仅当外键字段包含在 list_display 元组中时才会发生此行为。任何一位。

[更新]类别型号代码:

class Category(models.Model):
    title = models.CharField(max_length=256)
    parent = models.ForeignKey('self')
    project = models.NullBooleanField(default=False)
    created = models.DateTimeField(auto_now_add=True, editable=False)
    slug = models.SlugField(max_length=256, blank=True)

    def __unicode__(self):
        return self.title
4

1 回答 1

17

此行为是由某处未声明为可为空但在数据库中具有空值的外键关系引起的。当您在 list_display 中有 ManyToOne 关系时,更改列表类将始终使用 select_related 执行查询。(参见get_query_setdjango.contrib.admin.views.ChangeList 中的方法)。

select_related 默认情况下遵循每个对象上的所有外键,因此此查询发现的任何损坏的外键都将导致在评估查询时数据丢失。这不是特定于管理员的;您可以通过比较 Article.objects.all() 和 Article.objects.all().select_related() 的结果来交互式地测试它。

没有简单的方法来控制管理员将查找哪些外键 - select_related 需要一些参数,但管理员没有公开传递它们的方法。从理论上讲,您可以编写自己的 ChangeList 类并覆盖 get_query_set,但我不建议这样做。

真正的解决方法是确保您的外键模型字段在其 null 设置中准确反映数据库的状态。就个人而言,我可能会通过注释掉除 Category 以外的 Article 上的所有 FK 来做到这一点,看看这是否有帮助,然后将它们一一重新打开,直到事情开始破裂。问题不一定出在文章本身的 FK 上。如果修订、语言或类别的 FK 损坏,仍会导致连接丢失行。或者,如果他们相关的东西有损坏的 FK 等等。

于 2013-05-03T19:21:09.507 回答