简体   繁体   中英

How to implement multiple filters Django?

I want to add such filters to my internet shop:

Color:
 # red
 # blue
 # green
Material:
 # plastic
 # wood
 # metal

where each of points is a checkbox, color and material are fields of some Django model.

For example if i'm looking for red or blue toys with plastic material, i'll find it in such way:

filtered = SomeModel.objects.filter(material=plastic, color=red, color=blue)

But how to filter it dynamically?(if i have many filters)

You can do like

query = SomeModel.objects.filter(material='plastic')
if any_bool_condition:
    query = query.filter(color='red')

and you can keep adding filter on query .

For OR condition, you should look https://stackoverflow.com/a/6567918/3864717

Build your tuple with the colours you want, then use that in the query with __in .

Also, I've put strings in here, but if you're not already doing it, I'd suggest using an enum for things like this (unless the colours are user defined somehow maybe).

# this would be set from incoming checkbox values, and may be empty:
colours_to_filter = ('red', 'blue', 'green')
materials_to_filter = ()

query = SomeModel.objects.all()
if colours_to_filter:
    query = query.filter(colour__in=colours_to_filter)

if materials_to_filter:
    query = query.filter(material__in=materials_to_filter)

# Import
from django.db.models import Q

filter_query = Q()

# Get colors to be filtered
filter_color_list = ['red', 'blue']

# Add Filter by colors
filter_query.add(Q(color__in=filter_color_list), Q.AND)

# Get materials to be filtered
filter_material_list = ['plastic']

# Add filter by material
filter_query.add(Q(material__in=filter_material_list), Q.AND)

# Get filtered objects
filtered = SomeModel.objects.filter(filter_query)

You can add as many filters you want in filter_query, and if none of the filters added it will return all objects of the model.

I usually do these filterings by using query parameters .
It's based on what users checks for filtering whether it's multiple values or None values.

qs = SomeModel.objects.all()

material = request.GET.get("material")
color = request.GET.get("color")

if material:
    qs = qs.fitler(material__in=material)
if color:
    qs = qs.fitler(color__in=color)  

Notice that there is a package called django-filter . you can use this package for your filterings and it's pretty useful.
And your form would be like this: (EXAMPLE)

<form action="{% url 'view_url' %}" method="GET">
    <input type="checkbox" name="color" value="RED">
    <input type="checkbox" name="color" value="GREEN">
    <input type="checkbox" name="color" value="BLUE">
    <button type="submit" value="Submit">Submit</button>
</form>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM