在django中设置过滤器

时间:2009-11-24 08:44:19

标签: django filtering

我想在我的应用中设置一个过滤器...我想让我的过滤器按照增量完成,就像在this site运行一样。到目前为止,我的过滤视图是独立的(有没有一种方法可以将过滤逻辑组合到一个视图中?)我想我需要一些方法来保存所选择的过滤器(可能是会话......但我不确定这该怎么做)。我的代码如下:

def year_filter(request, year):   
vehicle_query = Vehicle.objects.filter(common_vehicle__year__year__exact=year).exclude(status__status='Incoming')
vehicle_list = vehicle_query.order_by('common_vehicle__series__model__manufacturer__manufacturer', 'common_vehicle__series__model__model', 'common_vehicle__year')

vehicle = paginate(request, vehicle_list)

year_count = vehicle_query.order_by('-common_vehicle__year__year').values('common_vehicle__year__year').annotate(count=Count('id'))
make_count = vehicle_query.order_by('common_vehicle__series__model__manufacturer__manufacturer').values('common_vehicle__series__model__manufacturer__manufacturer').annotate(count=Count('id'))
style_count = vehicle_query.order_by('common_vehicle__body_style__style').values('common_vehicle__body_style__style').annotate(count=Count('id'))
color_count = vehicle_query.order_by('exterior_colour__exterior_colour').values('exterior_colour__exterior_colour').annotate(count=Count('id'))

return render_to_response('vehicles.html', {'vehicle': vehicle, 'make_count': make_count, 'year_count': year_count, 'style_count': style_count, 'color_count': color_count,})

def make_filter(request, make):       
vehicle_query = Vehicle.objects.filter(common_vehicle__series__model__manufacturer__manufacturer=make).exclude(status__status='Incoming')
vehicle_list = vehicle_query.order_by('common_vehicle__series__model__manufacturer__manufacturer', 'common_vehicle__series__model__model', 'common_vehicle__year')

vehicle = paginate(request, vehicle_list)

year_count = vehicle_query.order_by('-common_vehicle__year__year').values('common_vehicle__year__year').annotate(count=Count('id'))
make_count = vehicle_query.order_by('common_vehicle__series__model__manufacturer__manufacturer').values('common_vehicle__series__model__manufacturer__manufacturer').annotate(count=Count('id'))
series_count = vehicle_query.order_by('common_vehicle__series__series').values('common_vehicle__series__series').annotate(count=Count('id'))
style_count = vehicle_query.order_by('common_vehicle__body_style__style').values('common_vehicle__body_style__style').annotate(count=Count('id'))
color_count = vehicle_query.order_by('exterior_colour__exterior_colour').values('exterior_colour__exterior_colour').annotate(count=Count('id'))

return render_to_response('vehicles.html', {'vehicle': vehicle, 'make_count': make_count, 'series_count': series_count, 'year_count': year_count, 'style_count': style_count, 'color_count': color_count,})

def series_filter(request, model):
vehicle_query = Vehicle.objects.filter(common_vehicle__series__series=model).exclude(status__status='Incoming')
vehicle_list = vehicle_query.order_by('common_vehicle__series__series', 'common_vehicle__series__model__model', 'common_vehicle__year')

vehicle = paginate(request, vehicle_list)

year_count = vehicle_query.order_by('-common_vehicle__year__year').values('common_vehicle__year__year').annotate(count=Count('id'))
make_count = vehicle_query.order_by('common_vehicle__series__model__manufacturer__manufacturer').values('common_vehicle__series__model__manufacturer__manufacturer').annotate(count=Count('id'))
style_count = vehicle_query.order_by('common_vehicle__body_style__style').values('common_vehicle__body_style__style').annotate(count=Count('id'))
color_count = vehicle_query.order_by('exterior_colour__exterior_colour').values('exterior_colour__exterior_colour').annotate(count=Count('id'))

return render_to_response('vehicles.html', {'vehicle': vehicle, 'make_count': make_count, 'year_count': year_count, 'style_count': style_count, 'color_count': color_count,})

def body_filter(request, body):
vehicle_query = Vehicle.objects.filter(common_vehicle__body_style__style=body).exclude(status__status='Incoming')
vehicle_list = vehicle_query.order_by('common_vehicle__series__model__manufacturer__manufacturer', 'common_vehicle__series__model__model', 'common_vehicle__year')

vehicle = paginate(request, vehicle_list)

year_count = vehicle_query.order_by('-common_vehicle__year__year').values('common_vehicle__year__year').annotate(count=Count('id'))
make_count = vehicle_query.order_by('common_vehicle__series__model__manufacturer__manufacturer').values('common_vehicle__series__model__manufacturer__manufacturer').annotate(count=Count('id'))
style_count = vehicle_query.order_by('common_vehicle__body_style__style').values('common_vehicle__body_style__style').annotate(count=Count('id'))
color_count = vehicle_query.order_by('exterior_colour__exterior_colour').values('exterior_colour__exterior_colour').annotate(count=Count('id'))

return render_to_response('vehicles.html', {'vehicle': vehicle, 'make_count': make_count, 'year_count': year_count, 'style_count': style_count, 'color_count': color_count,})

def color_filter(request, color):
vehicle_query = Vehicle.objects.filter(exterior_colour__exterior_colour=color).exclude(status__status='Incoming')
vehicle_list = vehicle_query.order_by('common_vehicle__series__model__manufacturer__manufacturer', 'common_vehicle__series__model__model', 'common_vehicle__year')

vehicle = paginate(request, vehicle_list)

year_count = vehicle_query.order_by('-common_vehicle__year__year').values('common_vehicle__year__year').annotate(count=Count('id'))
make_count = vehicle_query.order_by('common_vehicle__series__model__manufacturer__manufacturer').values('common_vehicle__series__model__manufacturer__manufacturer').annotate(count=Count('id'))
style_count = vehicle_query.order_by('common_vehicle__body_style__style').values('common_vehicle__body_style__style').annotate(count=Count('id'))
color_count = vehicle_query.order_by('exterior_colour__exterior_colour').values('exterior_colour__exterior_colour').annotate(count=Count('id'))

return render_to_response('vehicles.html', {'vehicle': vehicle, 'make_count': make_count, 'year_count': year_count, 'style_count': style_count, 'color_count': color_count,})

2 个答案:

答案 0 :(得分:2)

这种逻辑是managers的用途。即使您决定不使用经理,也应该以您熟悉的其他方式分解公共代码。 (首选程序编程?编写一个实用程序函数。熟悉OOP?创建可调用的基于类的视图,它继承自包含过滤逻辑的类。)如果你发现自己复制并粘贴这样的代码,那就表明你是不久之后会遇到麻烦。

答案 1 :(得分:1)

你写了一个经理。在您的示例中,vehicle_query至少需要一种方法,.annotate(count=Count('id'))需要一种方法,而重复order_by()则需要一种方法。

如果你需要嵌套的方法,那么你可以vehicle_query(year).with_counts()以及with_counts().vehicle_query(year),你也需要创建自己的QuerySet,即:从QuerySet继承,在那里添加方法,然后在管理器中使用该查询集,并将管理器中的方法映射到查询集中的方法。

from django.db import models
from django.db.models.query import QuerySet

class VehicleQuerySet(QuerySet):
    def vehicle_query(self, year):
        return self.filter(common_vehicle__year__year__exact=year).exclude(status__status='Incoming')

class VehicleManager(models.Manager):
    def get_query_set(self):
        return VehicleQuerySet(self.model)

    def vehicle_query(self, year):
        return self.get_query_set().vehicle_query(year)

class WhateverModel(models.Model):
    ...
    objects = models.Manager() # keeping the default manager
    smart_objects = VehicleManager() # additional manager

然后在你的观点中:

vehicle_query = Vehicle.smart_objects.vehicle_query(year)