7

我正在尝试按对象相关外键集中的特定值对 Django 管理列表页面进行排序。

具体来说,在下面的代码中,我希望 ContentAdmin 视图显示按“Twitter Score”(名称为“Twitter”的 Score 对象)排序的所有内容对象的列表。

在 django 应用程序中,我有以下模型:

class Content(models.Model):
    body = models.CharField(max_length=564)
    title = models.CharField(max_length=64) 

class Score(models.Model):
    name = models.CharField(max_length=64)
    score = models.IntegerField()
    content = models.ForeignKey('Content')

在 admin.py 我有以下内容:

class ContentAdmin(admin.ModelAdmin):
    list_display = ('title', 'show_twitter_score',)

    def show_twitter_score(self, obj):
        twitter_score = obj.score_set.get(name='Twitter')
        return 'Twitter: ' + str(twitter_score.score)

目标:ContentAdmin 的管理面板显示按“Twitter”分数排序的内容对象

谢谢大家!

4

3 回答 3

5

我通过扩展类的get_queryset方法解决了这个问题ContentAdmin。之后,只需获取正确的 ORM 查询即可

def get_queryset(self, request):
    qs = super(ContentAdmin, self).get_queryset(request)
    return qs.filter(score__name='Twitter').order_by('-score__score')

对于 Django 1.5 及更早版本,该方法是queryset.

def queryset(self, request):
    qs = super(ContentAdmin, self).queryset(request)
    return qs.filter(score__name='Twitter').order_by('-score__score')
于 2012-04-20T21:02:20.747 回答
1

如果我理解正确,您可以从Django 文档中的ModelAdmin.list_display尝试此操作:

通常,list_display不是实际数据库字段的元素不能用于排序(因为 Django 在数据库级别进行所有排序)。

但是,如果一个元素list_display表示某个数据库字段,则可以通过设置该项的admin_order_field属性来表明这一事实。

例如:

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    color_code = models.CharField(max_length=6)

    def colored_first_name(self):
        return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name)
    colored_first_name.allow_tags = True
    colored_first_name.admin_order_field = 'first_name'

class PersonAdmin(admin.ModelAdmin):
    list_display = ('first_name', 'colored_first_name')

上面将告诉 Django 在管理员中尝试按 colour_first_name 排序时按 first_name 字段排序。

您可以在代码中尝试此解决方法进行排序。

于 2012-04-19T19:33:45.287 回答
-2

由于 django admin 使用 db 进行排序,因此您无法对列表中显示的功能进行排序。

您可以做的是将要显示的列添加到 django 管理员用来列出您的模型的查询集中,这样您就可以进行排序。

要添加您需要的列,您必须使用 queryset extra 方法。

这应该可以解决问题:)

Content.objects.all().extra(select={'twitter_score': 'SELECT score from content_score WHERE content_score.id = content_content.id'})

奖金回合:

Content.objects.all().extra(select={'twitter_score': 'SELECT 'Twitter score:' || score from content_score WHERE content_score.id = content_content.id'})

于 2012-04-19T19:53:00.920 回答