【问题标题】:Setting up a filter in django在 django 中设置过滤器
【发布时间】:2010-12-19 19:28:56
【问题描述】:

我想在我的应用程序中设置一个过滤器...我想让我的过滤器以增量方式完成,有点像 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,})

【问题讨论】:

    标签: django filtering


    【解决方案1】:

    这种逻辑就是managers 的用途。即使您决定不使用管理器,您也应该以您熟悉的其他方式分解出通用代码。 (更喜欢过程编程?编写一个实用函数。熟悉 OOP?创建可调用的基于类的视图,这些视图继承自包含过滤逻辑的类。)如果您发现自己像这样复制和粘贴代码,这表明您正在很快就会遇到麻烦。

    【讨论】:

    • 那么我该如何解决我的问题呢?我不太擅长 Django……这是我的第一个应用 BTW
    【解决方案2】:

    你写了一个经理。从您的示例中,它至少需要一种方法用于vehicle_query,一种方法用于.annotate(count=Count('id')),并且可能需要一些用于重复的order_by()s。

    如果你需要嵌套方法,这样你就可以做到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)
    

    【讨论】:

    • 还有其他方法可以做到这一点...也许使用会话?也许只有我一个人,但我无法开始理解这段代码
    • 这是一种很常见的方式。按照 ozan 链接了解经理。
    • 顺便说一句,这会在查询之间保留我的值吗?
    • 只是想知道...有没有办法将所有值(即年份、品牌、系列、颜色和车身样式)作为一个函数(例如车辆查询)传递?
    • 47,当然。要么您必须从单个方法返回 year_count、make_count 等,要么您需要为每个方法返回一个方法。你学过python教程吗?请参阅如何在函数/方法中一次返回多个内容。
    猜你喜欢
    • 1970-01-01
    • 2021-12-15
    • 1970-01-01
    • 2021-04-10
    • 2020-01-10
    • 2014-07-12
    • 2020-11-13
    • 2010-12-31
    • 1970-01-01
    相关资源
    最近更新 更多