如何自定义Django Admin Filter

时间:2015-04-27 21:25:12

标签: django

使用django 1.7.7 管理页面,我想在表格中列出数据,我可以对其进行排序和过滤。 这正是文档中的图片显示的内容: https://docs.djangoproject.com/en/1.7/ref/contrib/admin/ 在list_filter部分下。 我试过了,但得到了一个错误: 'list_display [0]'的值是指'book_type',它不是可调用的。 然后,我尝试了这个:

# model.py:
class Interp():
    """ specifies the interpretation model """
    BOOK_TYPES = ['drama', 'scietific']
    BOOK_TYPES = tuple(zip(BOOK_TYPES, BOOK_TYPES))
    comment = models.CharField(max_length=20)
    book_type = models.CharField(max_length=20, choices=BOOK_TYPES,
                                   default='not specified')
    def __unicode__(self):
        return self.book_type

# admin.py:
class bookTypeFilter(SimpleListFilter):                                           
      title = 'book type'                                                           
      parameter_name = 'book_type'                                                  

      def lookups(self, request, model_admin):                                        
          types = set([t.book_type for t in model_admin.model.objects.all()])       
          return zip(types, types)                                                    

      def queryset(self, request, queryset):                                          
          if self.value():                                                            
              return queryset.filter(book_type__id__exact=self.value())             
          else:                                                                       
              return queryset                                                         


  class AdminInterpStore(admin.ModelAdmin):                                           
      """ admin page setting """                                                      
      search_fields = ('comment', 'book_type')                                          
      list_display = ('book_type',)                                                 
      list_filter = (bookTypeFilter, )

这显示了一个侧边栏并列出了值,但是当我点击其中任何一个时,我收到一个错误:

FieldError: Unsupported lookup 'id' for CharField or join on the field not permitted
  • 如何制作过滤器,最好是桌面视图?
  • 是否可以查看django1.7.7的完整示例,以便过滤管理页面?

1 个答案:

答案 0 :(得分:1)

您必须替换

return queryset.filter(book_type__id__exact=self.value()) 

通过

return queryset.filter(book_type=self.value())

有关详细信息,请参阅https://docs.djangoproject.com/en/1.8/ref/models/querysets/#field-lookups

此外,在lookups方法中,使用:

types = model_admin.model.objects.distinct('book_type').values_list('book_type', flat=True)

会更有效率,因为你不会从数据库中检索整个数据然后过滤它。

修改 我意识到book_type字段是choice字段。

首先,传递给choices参数的值必须是

  

一个可迭代的(例如,一个列表或元组),它由两个项目的可迭代组成(例如[(A,B),(A,B)......] A是存储在数据库中的值,B a人类可读的价值)

因此传递字符串列表将失败。

其次,Django管理员对此类字段的默认行为正是您要尝试实现的,因此在list_filter = ('book_type', )中设置AdminInterpStore就足够了。