这是针对Django 1.8 的
型号.py
class ProductClass(models.Model):
product_class = models.CharField(max_length=30)
def __unicode__(self):
return self.secondary_class
class Product(models.Model):
name= models.CharField(max_length=30)
product_class = models.ForeignKey(ProductClass, db_index=True)
def __unicode__(self):
return self.name
我想在ProductAdmin中显示一个列表过滤器,如果"产品分类"在每个条目旁边都有产品数量,则会显示列表。
按产品类别
- 书籍(100)
- 笔(10)
- 标尺(33)
我已经为的超级数据集做到了这一点
admin.py
class DynamicProductClassFilter(admin.SimpleListFilter):
title = _('Product Class')
# Parameter for the filter that will be used in the URL query.
parameter_name = 'p_class'
def lookups(self, request, model_admin):
classes = ProductClass.objects.annotate(number_products=Count('product'))
return [(c.id, '%s (%s)' % (c.product_class , c.number_products)) for c in classes]
现在,我想根据应用于数据集的其他过滤器进行更新,无论是搜索条件还是应用的其他列表过滤器。
我想我可以使用这样一个事实,即"request"one_answers"model_admin"在列表过滤器的"defqueryset"中可用。经过多次不同的尝试,我最终得到了以下代码
def lookups(self, request, model_admin):
products = model_admin.get_queryset(request)
product_ids = products.values_list('id', flat=True)
classes = ProductClass.objects.filter(product__id__in=product_ids).annotate(number_products=Count('product'))
return [(c.id, '%s (%s)' % (c.product_class, c.number_products)) for c in classes]
但不幸的是,这并没有将过滤器应用于主数据集。
我是django和python的新手,所以如果这里缺少基本知识,我深表歉意。
我已经找到了一个适合我的解决方案,但我仍然希望得到关于如何以更通用/更可维护的方式做得更好的反馈/建议。
def lookups(self, request, model_admin):
concept_filter = request.GET.get('p_concept', None)
if concept_filter:
classes = ProductClass.objects.filter(product__title__concept_id=concept_filter).annotate(number_products=Count('product'))
else:
classes = ProductClass.objects.annotate(number_products=Count('product'))
return [(c.id, '%s (%s)' % (c.product_class, c.number_products)) for c in classes]
我发现我可以通过使用来获得应用于变更列表数据集的过滤标准
concept_filter = request.GET.get('p_concept', None)
对于我的用例来说,这很好,因为我更希望这个列表过滤器只依赖于另一个过滤器。
了解如何修改此解决方案会很有意思,这样您就可以遍历所有查询参数并了解如何正确构建查询。不过,我不知道从哪里可以获得参数名称和它需要过滤的列之间的关联。也许只是命名约定会有所帮助。