开发者

Setting up a filter in django

开发者 https://www.devze.com 2022-12-12 03:19 出处:网络
I\'d like to set up a filter in my app...I\'d like to have my filters being done in increments, kinda like what is running at this site.So far my filter views are separate (is there a way of combining

I'd like to set up a filter in my app...I'd like to have my filters being done in increments, kinda like what is running at this site. So far my filter views are separate (is there a way of combining the filtering logic into one view?) and I'm supposing I'll need some way of saving the chosen filter (possibly sessions...but I'm not sure how to do this). My code is as below:

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,})


This sort of logic is what managers are for. Even if you decide not to use managers, you should be factoring out common code in some other way that you're familiar with. (Prefer procedural programming? Write a utility function. Familiar with OOP? Create callable class-based views which inherit from a class that contains the filtering logic.) If you find yourself copying and pasting code like this, it's a sign that you're going to run into trouble before too long.


You write a manager. From your example it needs at least one method for vehicle_query, one method for .annotate(count=Count('id')) and maybe some for the repeated order_by()s.

If you need the methods to nest, so that you can do vehicle_query(year).with_counts() as well as with_counts().vehicle_query(year), you need to make your own QuerySet too, that is: inherit from QuerySet, add the methods there, then use that queryset in your manager, and map methods in the manager to the methods in the 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

Then in your views:

vehicle_query = Vehicle.smart_objects.vehicle_query(year)
0

精彩评论

暂无评论...
验证码 换一张
取 消