django管理员列表过滤器查询集取决于更改列表结果

时间:2015-11-17 17:04:51

标签: django django-admin django-filters

这适用于Django 1.8

models.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'和'model_admin'在列表过滤器的'def queryset'中可用的事实。经过多次尝试后,我最终得到了以下代码

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的新手,所以如果这里缺少基本知识我会道歉。

1 个答案:

答案 0 :(得分:0)

我现在找到了一个适合我的解决方案,但我仍然希望得到关于如何更好地以更通用/可维护的方式做到这一点的反馈/建议。

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)

对于我的用例而言工作正常,因为我希望此列表过滤器仅依赖于另一个过滤器。

知道如何修改此解决方案以便您可以遍历所有查询参数并知道如何正确构造查询,这将会很有趣。我不知道在哪里可以获得参数名称与其需要过滤的列之间的关联。也许只是命名约定会有所帮助。