others - 优化Queryset结果的过滤器

我正在重写Django Admin's list_filter (在Django管理用户界面右侧的筛选器自定义显示listview),下面的代码有效,但未优化:

(要关注的部分,在下面的代码例子中,qs.values_list('product_category', flat=True)这只返回id (int ),所以,我必须使用ProductCategory.objects.get(id=i)

是否可以简化这个操作?


from django.utils.translation import ugettext_lazy as _


from django.contrib.admin import SimpleListFilter


from product_category.model import ProductCategory



class ProductCategoryFilter(SimpleListFilter):


 title = _('ProductCategory')


 parameter_name = 'product_category'



 def lookups(self, request, model_admin):


 qs = model_admin.get_queryset(request)



 ordered_filter_obj_list = []


 # TODO: Works, but increases SQL queries by"number of product categories"


 for i in (


 qs.values_list("product_category", flat=True)


 .distinct()


 .order_by("product_category")


 ):


 cat = ProductCategory.objects.get(id=i)


 ordered_filter_obj_list.append((i, cat))



 return ordered_filter_obj_list



 def queryset(self, request, queryset):


 if self.value():


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



# P.S. Above filter is used in another class like so


class ItemAdmin(admin.ModelAdmin):


 list_filter = (ProductCategoryFilter,)



时间:

你可能在寻找select_related,我不知道你的确切模型结构,但是你可以使用它,如下所示:


cats = set()



for p in Product.objects.all().select_related('category'):


 # Without select_related(), this would make a database query for each


 # loop iteration in order to fetch the related categories for each product.


 cats.add(p.category)



我认为你的产品和ProductCategory模型之间存在某种关系。

然后使用这个临时dict查找关联的字符串值。


def lookups(self, request, model_admin):


 qs = model_admin.get_queryset(request)



 category_list = {}


 for x in ProductCategory.objects.all():


 category_list[x.id] = str(x)



 ordered_filter_obj_list = []


 for i in (


 qs.values_list("product_category", flat=True)


 .distinct().order_by("product_category")


 ):


 ordered_filter_obj_list.append((i, category_list[i]))



 return ordered_filter_obj_list



可以在单个SQL查询中完成,也可以通过Django ORM进行:


def lookups(self, request, model_admin):


 qs = model_admin.get_queryset(request).select_related('product_category')


 values = qs.values('product_category_id', 'product_category__name') #assuming ProductCategory has an attribute 'name'


 unique_categories = values.distinct('product_category_id', 'product_category__name')


 return unique_categories.items()



...