Overview
Numeric filters provide specialized interfaces for filtering integer, float, and decimal fields. They support exact value matching, range filtering, and interactive slider controls.
Numeric filters work with IntegerField, FloatField, DecimalField, and AutoField.
Available Numeric Filters
SingleNumericFilter Filter by exact numeric value
RangeNumericFilter Filter by min/max range with text inputs
RangeNumericListFilter Range filter for custom SimpleListFilter
SliderNumericFilter Interactive range slider for visual filtering
SingleNumericFilter
Filter by an exact numeric value.
Basic Usage
from django.db import models
class Product ( models . Model ):
name = models.CharField( max_length = 200 )
price = models.DecimalField( max_digits = 10 , decimal_places = 2 )
stock = models.IntegerField( default = 0 )
rating = models.FloatField( null = True , blank = True )
from django.contrib import admin
from unfold.admin import ModelAdmin
from unfold.contrib.filters.admin import SingleNumericFilter
from .models import Product
@admin.register (Product)
class ProductAdmin ( ModelAdmin ):
list_display = [ "name" , "price" , "stock" , "rating" ]
list_filter = [
( "stock" , SingleNumericFilter),
( "rating" , SingleNumericFilter),
]
Users can type an exact number to filter results. Great for ID lookups or specific quantity searches.
Custom Parameter Name
from unfold.contrib.filters.admin import SingleNumericFilter
class CustomStockFilter ( SingleNumericFilter ):
parameter_name = "exact_stock"
@admin.register (Product)
class ProductAdmin ( ModelAdmin ):
list_filter = [
( "stock" , CustomStockFilter),
]
RangeNumericFilter
Filter by a minimum and maximum value range.
Basic Usage
from unfold.contrib.filters.admin import RangeNumericFilter
@admin.register (Product)
class ProductAdmin ( ModelAdmin ):
list_display = [ "name" , "price" , "stock" ]
list_filter = [
( "price" , RangeNumericFilter),
( "stock" , RangeNumericFilter),
]
This creates two input fields:
From : Minimum value (greater than or equal to)
To : Maximum value (less than or equal to)
Example Usage
Filter applies query
Query becomes: queryset.filter( price__gte = 10 , price__lte = 50 )
Results display
Only products with price between 10 a n d 10 and 10 an d 50 are shown.
Partial Ranges
Users can enter only “From” or only “To”:
# Only "From: 100" entered
queryset.filter( price__gte = 100 )
# Only "To: 500" entered
queryset.filter( price__lte = 500 )
RangeNumericListFilter
Range filter for custom SimpleListFilter classes.
Basic Usage
from unfold.contrib.filters.admin import RangeNumericListFilter
class PriceRangeFilter ( RangeNumericListFilter ):
title = "Price Range"
parameter_name = "price"
def lookups ( self , request , model_admin ):
# Required but not used for range filters
return (( "dummy" , "dummy" ),)
@admin.register (Product)
class ProductAdmin ( ModelAdmin ):
list_filter = [PriceRangeFilter]
The lookups() method is required by Django but not used. Just return a dummy tuple.
Custom Field Filtering
class CustomPriceFilter ( RangeNumericListFilter ):
title = "Discounted Price"
parameter_name = "discount_price"
def queryset ( self , request , queryset ):
value_from = self .used_parameters.get( f " { self .parameter_name } _from" )
value_to = self .used_parameters.get( f " { self .parameter_name } _to" )
filters = {}
if value_from:
filters[ f "discount_price__gte" ] = value_from
if value_to:
filters[ f "discount_price__lte" ] = value_to
return queryset.filter( ** filters) if filters else queryset
def lookups ( self , request , model_admin ):
return (( "dummy" , "dummy" ),)
SliderNumericFilter
Interactive range slider for visual filtering.
Basic Usage
from unfold.contrib.filters.admin import SliderNumericFilter
@admin.register (Product)
class ProductAdmin ( ModelAdmin ):
list_display = [ "name" , "price" , "stock" ]
list_filter = [
( "price" , SliderNumericFilter),
( "stock" , SliderNumericFilter),
]
The slider automatically calculates min/max values from your database and creates an interactive UI.
How It Works
The slider:
Queries the database to find minimum and maximum values
Creates a draggable range slider with those bounds
Updates the filter as users drag the handles
Shows current min/max values below the slider
Custom Step Size
Control the increment between values:
class PriceSliderFilter ( SliderNumericFilter ):
STEP = 10 # Increment by 10
@admin.register (Product)
class ProductAdmin ( ModelAdmin ):
list_filter = [
( "price" , PriceSliderFilter),
]
Decimal Precision
For float and decimal fields:
class RatingSliderFilter ( SliderNumericFilter ):
MAX_DECIMALS = 2 # Show 2 decimal places
STEP = 0.1 # Increment by 0.1
@admin.register (Product)
class ProductAdmin ( ModelAdmin ):
list_filter = [
( "rating" , RatingSliderFilter),
]
Advanced Configuration
class AdvancedSliderFilter ( SliderNumericFilter ):
MAX_DECIMALS = 3
STEP = 0.5
def choices ( self , changelist ):
# Customize slider appearance
for choice in super ().choices(changelist):
# choice contains min, max, step, decimals
yield choice
@admin.register (Product)
class ProductAdmin ( ModelAdmin ):
list_filter = [
( "price" , AdvancedSliderFilter),
]
Field Type Support
IntegerField
class Product ( models . Model ):
stock = models.IntegerField()
list_filter = [
( "stock" , RangeNumericFilter), # Works perfectly
]
FloatField
class Product ( models . Model ):
rating = models.FloatField()
list_filter = [
( "rating" , SliderNumericFilter), # Automatically handles decimals
]
DecimalField
from decimal import Decimal
class Product ( models . Model ):
price = models.DecimalField( max_digits = 10 , decimal_places = 2 )
list_filter = [
( "price" , RangeNumericFilter), # Respects decimal places
]
AutoField (Primary Keys)
# Filter by ID range
list_filter = [
( "id" , RangeNumericFilter),
]
Error Handling
Filters automatically handle invalid input:
# User enters "abc" in numeric field
# Filter ignores invalid input and shows all results
Type Validation
from unfold.contrib.filters.admin import SingleNumericFilter
class Product ( models . Model ):
name = models.CharField( max_length = 200 ) # Not numeric!
@admin.register (Product)
class ProductAdmin ( ModelAdmin ):
list_filter = [
( "name" , SingleNumericFilter), # Raises TypeError
]
Applying numeric filters to non-numeric fields raises a TypeError. Ensure you only use them with compatible field types.
Combining Filters
Use multiple numeric filters together:
from unfold.contrib.filters.admin import (
RangeNumericFilter,
SingleNumericFilter,
SliderNumericFilter,
)
@admin.register (Product)
class ProductAdmin ( ModelAdmin ):
list_filter = [
( "price" , SliderNumericFilter), # Visual range
( "stock" , RangeNumericFilter), # Text inputs
( "id" , SingleNumericFilter), # Exact match
]
SliderNumericFilter runs two aggregate queries to find min/max values:queryset.aggregate( min = Min( 'price' ), max = Max( 'price' ))
For large tables, consider:
Adding database indexes
Using RangeNumericFilter instead
Caching min/max values
Add indexes to filtered numeric fields: class Product ( models . Model ):
price = models.DecimalField(
max_digits = 10 ,
decimal_places = 2 ,
db_index = True # Add index
)
Range filters use __gte and __lte lookups efficiently: # Efficient query
Product.objects.filter( price__gte = 10 , price__lte = 50 )
Ensure your database can use indexes for these lookups.
Styling and Templates
Templates Used
SingleNumericFilter : unfold/filters/filters_numeric_single.html
RangeNumericFilter : unfold/filters/filters_numeric_range.html
SliderNumericFilter : unfold/filters/filters_numeric_slider.html
JavaScript Dependencies
Slider filter uses:
noUiSlider : Range slider component
wNumb : Number formatting
Both are included automatically via Media class.
API Reference
SingleNumericFilter
URL parameter name. Defaults to field path.
template
str
default: "\"unfold/filters/filters_numeric_single.html\""
Template used to render the filter
RangeNumericFilter
Base parameter name. Creates {name}_from and {name}_to parameters.
template
str
default: "\"unfold/filters/filters_numeric_range.html\""
Template used to render the filter
SliderNumericFilter
STEP
int | float | None
default: "None"
Increment between slider values. Auto-calculated if not set.
Maximum decimal places for float/decimal fields
template
str
default: "\"unfold/filters/filters_numeric_slider.html\""
Template used to render the filter
Best Practices
Choose the right filter
SingleNumericFilter : For exact value lookups (IDs, specific quantities)
RangeNumericFilter : For precise range filtering with keyboard input
SliderNumericFilter : For visual exploration and approximate ranges
Consider user experience
Use sliders for fields with reasonable ranges (1-1000)
Use text inputs for fields with large ranges (1-1000000)
Provide visual feedback with current values
Optimize performance
Add database indexes to filtered fields
Cache min/max values for sliders if possible
Use select_related() for related field filters
Next Steps
Date/Time Filters Learn about date and datetime range filters
Text Filters Explore text-based search filters