2016-11-25 65 views
1

我是Python和Django的新手。Django Admin list_display添加列[相关外键的计数记录]

我正在尝试计算模型的外键项目/记录,并将其显示为Admin list_display中的列。

所以我有一个模型“作者”,作为模型“书”的外键。

这里的models.py:

class Author(models.Model): 

    name = models.CharField(
     max_length=100, 
    ) 

    class Meta: 
     ordering = ['-name '] 
     verbose_name = _('Author') 
     verbose_name_plural = _('Authors') 

    def __str__(self): 
     return self.author 

    @models.permalink 
    def get_absolute_url(self): 
     return reverse('author_detail', kwargs={'pk': self.pk}) 

class Book(models.Model): 
    author = models.ForeignKey(
     'Author', 
     related_name='menu_items', 
     verbose_name=_('author'), 
    ) 

    bookname= models.CharField(
     max_length=100, 
    ) 

    publisher= models.CharField(
     max_length=100, 
    ) 
    class Meta: 
     ordering = ['-bookname'] 
     verbose_name = _('Book') 
     verbose_name_plural = _('Books') 

    def __str__(self): 
     return self.bookname 

    @models.permalink 
    def get_absolute_url(self): 
     return ('book_detail', [self.pk]) 

这里的admin.py

from django.contrib import admin 
from .models import Author, Book 

class BookInline(admin.TabularInline): 
    model = Book 
    extra = 1 

@admin.register(Author) 
class LibraryAdmin(admin.ModelAdmin): 
    def NumberOfBooks(self, obj): 
     #I guess sth is wrong here when trying to count the book_set 
     return obj.book_set.count() 

    NumberOfBooks.short_description = "Books Count" 
    list_display = ['bookname', 'publisher', 'NumberOfBooks'] 
    inlines = [BookInline] 

我要统计每个作者有多少本书中写道,并显示像这样的的第二级管理页面首页>作者>作者

Author | Books Count 
Someone1 NumberOfBooks 
Someone2 NumberOfBooks 
Someone3 NumberOfBooks 
Someone4 NumberOfBooks 

但是我得到的错误:错误

'Author' object has no attribute 'book_set' 

1.我要做这obj.book_set.count()? 我以为obj.book_set会在同一个“作者”(obj)下提到“书”,听起来像我误解了它,但我不知道如何实现我的意图。

2.相反,如果我想为'作者'添加一个字段来自动统计与每个作者有关的“书”数量,这应该是一个更好的方法,那么该怎么做?

回答

4

应该有与错误页面上的所有可用字段列表,你应该找到一个域名为menu_items(这就是你投入related_nameBook模型)。

但这可能不是最好的选择。你应该能够覆盖get_queryset()方法您LibraryAdmin(admin.ModelAdmin)类是这样的:

... 
from django.db.models import Count 
... 

@admin.register(Loan) 
class LibraryAdmin(admin.ModelAdmin): 

    def get_queryset(self, request): 
     qs = super(LibraryAdmin, self).get_queryset(request) 
     return qs.annotate(books_count=Count('menu_items')) 

    def books_count(self, inst): 
     return inst.books_count 

    list_display = ['bookname', 'publisher', 'books_count'] 
    inlines = [BookInline] 

这样计数将由您的DB来完成。

+0

' 错误: :(admin.E108)'list_display [3]'的值是指'books_count',它不是可调用的,'LibraryAdmin ',或'作者。作者'的属性或方法.' –

+0

这就是我得到的错误,我现在很困惑... 顺便说一下'@admin.register(Loan)'应该是'@admin .register(作者)',我输入错了,但这不是问题,例如为了让我更容易理解,我改了一些名字。 –

+0

我最后加入得到这个工作: '高清show_books_count(自我,研究院): \t \t回inst.books_count \t list_display = [ 'BOOKNAME', '发行人', 'show_books_count']' 但你能解释一下为什么这个工作和'(self,inst)'做了什么?可以简化并添加到'def get_queryset'中? –