django管理员对所有过滤对象的操作

时间:2009-12-28 01:40:39

标签: django search filter admin action

管理员操作可以对列表页面中的选定对象执行操作。 是否可以对所有过滤的对象进行操作?

例如,如果管理员搜索以“T-shirt”开头的产品名称,其中包含400种产品,并希望将所有产品的价格提高10%。 如果管理员一次只能修改一页结果,则需要花费很多精力。

由于

2 个答案:

答案 0 :(得分:2)

自定义动作应该用于一组选定的对象,所以我认为没有一种标准的方法可以做你想要的。

但我认为我有一个可能对你有用的黑客......(意思是:使用风险并且未经测试)

在您的操作函数中,request.GET将包含管理搜索中使用的q参数。因此,如果您在搜索中输入“T-Shirt”,您应该看到request.GET类似于:

<QueryDict: {u'q': [u'T-Shirt']}>

您可以完全忽略自定义操作函数接收的查询字符串参数,并根据request.GET的q参数构建您自己的查询集。类似的东西:

def increase_price_10_percent(modeladmin, request, queryset):
    if request.GET['q'] is None:
        # Add some error handling
    queryset=Product.objects.filter(name__contains=request.GET['q'])
    # Your code to increase price in 10%
increase_price_10_percent.short_description = "Increases price 10% for all products in the search result"

我会确保禁止q为空的任何请求。在您阅读name__contains的地方,您应该模仿您为产品对象管理员创建的任何过滤器(因此,如果搜索仅查看名称字段,name__contains可能就足够了;如果查看在名称和描述中,你在动作函数中也会有一个更复杂的过滤器。)

我也可以添加一个中间页面,说明哪些模型会受到影响,并让用户点击“我真的知道我在做什么”确认按钮。查看django.contrib.admin.actions的代码,了解如何列出要删除的对象的示例。它应该指向正确的方向。

注意:用户仍然需要在管理页面中选择一些内容,否则动作函数永远不会被调用。

答案 1 :(得分:2)

这是一个更通用的解决方案,没有经过全面测试(而且非常天真),所以它可能会破坏奇怪的过滤器。对我来说,使用日期过滤器,外键过滤器,布尔过滤器。

def publish(modeladmin,request,queryset):
    kwargs = {}
    for filter,arg in request.GET.items():
        kwargs.update({filter:arg})
    queryset = queryset.filter(**kwargs)
    queryset.update(published=True)