A reusable Django app that provides advanced admin filters for CharField fields, including both dropdown select and autocomplete functionality.
- Features
- Installation
- Quick Start
- Usage
- Configuration
- Examples
- How It Works
- Performance Considerations
- Troubleshooting
- FAQ
- Requirements
- Contributing
- License
- Support
- Easy-to-use filters for CharField fields in Django admin
- Three filter types:
- Select: Dropdown with all unique values
- Autocomplete: Type-to-search functionality
- Autocomplete Select: Hybrid filter combining dropdown and search
- User-friendly interface with clear button for quick filter removal
- Dynamic filtering as you type
- Automatic title generation from field names
- Cached lookups for better performance
- Compatible with Django 4.2.0+
Install from PyPI using pip:
pip install django-charfield-filtersAdd charfield_filters to your INSTALLED_APPS in settings.py:
INSTALLED_APPS = [
...
'charfield_filters',
...
]That's it! No database migrations or additional configuration needed.
Here's a minimal example to get you started in 30 seconds:
# models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=200)
category = models.CharField(max_length=100)
brand = models.CharField(max_length=100)
# admin.py
from django.contrib import admin
from charfield_filters.admin import CharFieldFilterAdmin
from .models import Product
@admin.register(Product)
class ProductAdmin(CharFieldFilterAdmin):
list_display = ['name', 'category', 'brand']
charfield_filter_fields = ['category', 'brand']
charfield_filter_type = 'autocomplete_select'Now you have searchable dropdown filters for category and brand in your Django admin!
from django.contrib import admin
from charfield_filters.admin import CharFieldFilterAdmin
@admin.register(YourModel)
class YourModelAdmin(CharFieldFilterAdmin):
list_display = ['name', 'category'] # Fields to display
charfield_filter_fields = ['name', 'category'] # Fields to filter
charfield_filter_type = 'autocomplete_select' # 'select', 'autocomplete', or 'autocomplete_select'If you need to combine with other admin classes:
from django.contrib import admin
from charfield_filters.admin import CharFieldFilterMixin
@admin.register(YourModel)
class YourModelAdmin(CharFieldFilterMixin, admin.ModelAdmin):
list_display = ['name', 'category']
charfield_filter_fields = ['name', 'category']
charfield_filter_type = 'autocomplete_select'Choose the filter type that best matches your data and use case:
Classic dropdown filter with all available options.
charfield_filter_type = 'select'When to use:
- Fields with 2-20 unique values (e.g., status, priority, type)
- When users need to see all available options at a glance
- When exact matching is required
Features:
- Shows all unique values in a dropdown
- Provides exact matching
- Minimal UI, no search functionality
Search box with type-to-filter functionality.
charfield_filter_type = 'autocomplete'When to use:
- Fields with many unique values (e.g., product names, user emails)
- When users know what they're searching for
- When you want case-insensitive partial matching
Features:
- Text input with search functionality
- Case-insensitive partial matching (uses
__icontains) - No dropdown, pure search interface
- Dynamic filtering as you type
Hybrid filter combining dropdown and search functionality.
charfield_filter_type = 'autocomplete_select'When to use:
- Most use cases (this is the recommended default)
- Fields with 5-100 unique values
- When users might want to browse OR search
- When you want the best user experience
Features:
- Searchable dropdown with all options visible
- Clear button (Ă—) for quick filter removal
- Supports both browsing and searching
- Best of both worlds: discovery + search
charfield_filter_fields: List of CharField field names to create filters forcharfield_filter_type: Type of filter to use ('select', 'autocomplete', or 'autocomplete_select')
# models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
genre = models.CharField(max_length=50)
publisher = models.CharField(max_length=100)
isbn = models.CharField(max_length=13)
def __str__(self):
return self.title
class Magazine(models.Model):
name = models.CharField(max_length=200)
category = models.CharField(max_length=100)
frequency = models.CharField(max_length=50) # monthly, weekly, etc.
def __str__(self):
return self.name
# admin.py
from django.contrib import admin
from charfield_filters.admin import CharFieldFilterAdmin
from .models import Book, Magazine
@admin.register(Book)
class BookAdmin(CharFieldFilterAdmin):
list_display = ['title', 'author', 'genre', 'publisher']
charfield_filter_fields = ['author', 'genre', 'publisher']
charfield_filter_type = 'autocomplete_select'
search_fields = ['title', 'isbn']
@admin.register(Magazine)
class MagazineAdmin(CharFieldFilterAdmin):
list_display = ['name', 'category', 'frequency']
charfield_filter_fields = ['category', 'frequency']
charfield_filter_type = 'select' # Use simple dropdown for limited valuesYou can mix this package with other admin features:
from django.contrib import admin
from charfield_filters.admin import CharFieldFilterAdmin
@admin.register(Employee)
class EmployeeAdmin(CharFieldFilterAdmin):
list_display = ['name', 'department', 'position', 'status', 'hire_date']
# CharField filters from this package
charfield_filter_fields = ['department', 'position']
charfield_filter_type = 'autocomplete_select'
# Other standard admin features work normally
search_fields = ['name', 'email']
date_hierarchy = 'hire_date'
ordering = ['-hire_date']The mixin works seamlessly with Django's built-in filters:
from django.contrib import admin
from charfield_filters.admin import CharFieldFilterMixin
class OrderAdmin(CharFieldFilterMixin, admin.ModelAdmin):
list_display = ['order_id', 'customer', 'status', 'total', 'created_at']
# CharField filters for text fields
charfield_filter_fields = ['status', 'customer']
charfield_filter_type = 'autocomplete_select'
# Standard Django filters for other field types
list_filter = [
'created_at', # Date filter
'is_paid', # Boolean filter
]This package extends Django's admin filtering system by:
-
Dynamic Filter Creation: The
CharFieldFilterMixinintercepts theget_list_filter()method and dynamically creates filter classes for specified CharField fields. -
Custom Templates: Each filter type uses a custom HTML template with JavaScript for enhanced functionality (autocomplete, search, clear buttons).
-
Efficient Querying: Filters query the database for distinct values only when needed, with results cached per request.
-
Field Validation: Only actual CharField fields from your model are processed; non-existent fields are silently skipped.
Under the hood:
selectfilter: Uses exact matching (field_name=value)autocompletefilter: Uses case-insensitive partial matching (field_name__icontains=value)autocomplete_selectfilter: Combines both approaches with JavaScript-enhanced UI
The package executes a distinct query for each filtered field to populate dropdown options:
model._default_manager.distinct().order_by(field_name).values_list(field_name, flat=True)Tips for optimal performance:
-
Add Database Indexes: Index CharField fields that you filter frequently
class Product(models.Model): category = models.CharField(max_length=100, db_index=True) brand = models.CharField(max_length=100, db_index=True)
-
Choose the Right Filter Type:
- Use
selectfor fields with <20 unique values (single query) - Use
autocompletefor fields with >100 unique values (no initial query) - Use
autocomplete_selectfor everything in between
- Use
-
Limit Filtered Fields: Only add filters for fields users actually need
-
Monitor Query Count: Use Django Debug Toolbar to monitor the impact of filters on your query count
selectandautocomplete_select: One additional query per field per page loadautocomplete: No additional queries until user starts typing- Caching: Distinct values are fetched once per request and reused
Problem: Added charfield_filter_fields but filters don't show up.
Solutions:
- Verify
charfield_filtersis inINSTALLED_APPS - Check that field names in
charfield_filter_fieldsmatch your model exactly - Ensure the fields are actually
CharFieldinstances (notTextField,ForeignKey, etc.) - Clear your browser cache and restart the development server
Problem: FieldDoesNotExist: MyModel has no field named 'xyz'
Solution: Double-check spelling of field names in charfield_filter_fields. The package silently skips non-existent fields, but errors may appear if there's a typo in related configuration.
Problem: Filters appear but selecting values doesn't filter the results.
Solutions:
- Check browser console for JavaScript errors
- Ensure you're not overriding
get_queryset()in a way that ignores URL parameters - Verify the field values in your database actually match the filter options
Problem: Typing in autocomplete filter doesn't show results or filter.
Solutions:
- Verify JavaScript is enabled in the browser
- Check that the template files are being loaded (look for 404s in browser dev tools)
- Ensure there are no JavaScript conflicts with other admin customizations
Problem: Admin loads slowly with many filters.
Solutions:
- Add database indexes to filtered fields
- Switch from
autocomplete_selecttoautocompletefor fields with many values - Reduce the number of
charfield_filter_fields - Consider pagination settings in Django admin
Not directly with the current version. The charfield_filter_type applies to all fields in charfield_filter_fields. If you need different types, you can:
from charfield_filters.filters import create_charfield_filter
class MyAdmin(admin.ModelAdmin):
list_filter = [
create_charfield_filter('category', 'select'),
create_charfield_filter('brand', 'autocomplete_select'),
]No, this package is specifically designed for CharField fields. TextFields are typically too long and varied to filter effectively. For TextField filtering, consider using Django's built-in search functionality instead.
Yes! Override the templates in your project:
- Create a directory:
templates/admin/charfield_filters/ - Copy the template you want to customize from the package
- Modify it to your needs
Template files:
dropdown_filter.html- Select filterautocomplete_filter.html- Autocomplete filterautocomplete_select_filter.html- Autocomplete select filter
Yes! Version 0.1.3+ includes full dark mode support that automatically adapts to Django's admin dark mode.
No, this package is specifically for CharField. For ForeignKey filtering, use Django's built-in list_filter with the field name directly, or use autocomplete_fields for better UX.
Yes! The CharFieldFilterMixin is designed to work alongside other admin mixins and packages. Just ensure you inherit from the mixin before admin.ModelAdmin:
class MyAdmin(CharFieldFilterMixin, OtherMixin, admin.ModelAdmin):
passFilters work independently and are automatically combined with AND logic. Users can select values in multiple filters simultaneously, and Django will show only records matching all selected filters.
Yes, you can override changelist_view to set default filters:
class MyAdmin(CharFieldFilterAdmin):
def changelist_view(self, request, extra_context=None):
if not request.GET:
from django.http import QueryDict
q = QueryDict(mutable=True)
q['status'] = 'active'
request.GET = q
request.META['QUERY_STRING'] = request.GET.urlencode()
return super().changelist_view(request, extra_context=extra_context)- Python 3.8+
- Django 4.2.0+
MIT License - see LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
For more details, see CONTRIBUTING.md.
If you have any questions or need help with the package, please open an issue on GitHub.