2012-04-19 118 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