2012-04-19 96 views
5

我想按对象的相关外键集中的特定值对Django Admin列表页进行排序。Django管理:按值对相关外键排序

具体来说,在下面的代码中,我希望ContentAdmin视图显示按“Twitter分数”排序的所有内容对象(带有名称“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管理面板显示的内容对象由“推特”分数排序

谢谢大家!

+0

你的代码有什么问题? – 2012-04-19 19:13:06

+0

管理员面板你的意思是'admin.py'?你有'admin.site.register(Content,ContentAdmin)'吗? – 2012-04-19 19:23:16

+0

我的代码没有做排序,它只显示分数 – djs22 2012-04-19 19:23:34

回答

4

我通过扩展ContentAdmin类的get_queryset方法解决了这个问题。在此之后,它只是一个得到正确的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') 
0

如果我理解正确的,你可以从ModelAdmin.list_display Django的文档中试试这个:

通常情况下,是不实际的数据库字段不能在排序中使用的元素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由FIRST_NAME场试图通过在管理colored_first_name排序时订购。

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

+0

谢谢塞萨尔,但我不认为这对我有用。使用list_display我没有办法指定content_obj.score_set中我想要排序的多个分数中的哪一个。 另外,我可以为你澄清我的问题吗?我想确保每个人都能理解它 – djs22 2012-04-19 19:37:31

+0

当然,只需重新编辑您的帖子并改变您的需求即可。对不起,也许我误解了整个事情,不会是我第一次:( – 2012-04-19 19:38:50

+0

在底部做了一个小小的编辑GOAL,但不幸的是我不知道怎么说这个问题。谢谢你尝试塞萨尔! – djs22 2012-04-19 19:52:16

0

由于django管理员使用数据库进行排序,因此无法对列表中显示的函数进行排序。

您可以做的是将您想要显示的列添加到django admin用于列出模型的查询集,这样您可以进行排序。

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

这应该做的伎俩:)

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

奖金圆:

Content.objects.all()额外的(选择= { 'twitter_score':“选择 'Twitter的分数。' | |分数from content_score WHERE content_score.id = content_content.id'})

+0

在ORM的领域内完全可以做到这一点,我找到了一个解决方案,我很快就会发布,我会在这里发表评论:) – djs22 2012-04-19 21:12:16

+0

实际上,直到我回答时,我不准再过8个小时! – djs22 2012-04-19 21:18:15

+0

@ djs22我很好奇,看到这一个:) – 2012-04-20 07:40:36