Add pagination to inline formsets for better performance with large datasets
Paginated inlines allow you to split large sets of related objects across multiple pages, improving performance and user experience when dealing with models that have many related objects.
When a model has hundreds or thousands of related objects, displaying all of them at once can slow down page load times and overwhelm users. Pagination solves this by displaying a manageable subset of objects per page.
Uses PaginationInlineFormSet or PaginationGenericInlineFormSet (set automatically)
Creates a paginator for the inline’s queryset
Displays only the current page’s objects
Adds pagination controls below the inline
admin.py
from unfold.admin import TabularInlineclass ReviewInline(TabularInline): model = Review extra = 0 per_page = 25 # 25 reviews per page # formset is automatically set to PaginationInlineFormSet
The formset is automatically set to handle pagination, but you can customize it if needed:
admin.py
from unfold.forms import PaginationInlineFormSetfrom unfold.admin import TabularInlineclass CustomPaginatedFormSet(PaginationInlineFormSet): def get_queryset(self): """Customize the queryset for pagination""" qs = super().get_queryset() return qs.select_related('category').prefetch_related('tags')class ProductInline(TabularInline): model = Product formset = CustomPaginatedFormSet per_page = 20 fields = ['name', 'category', 'price']
If you provide a custom formset, make sure it inherits from PaginationInlineFormSet or PaginationGenericInlineFormSet to maintain pagination functionality.
class SimpleInline(TabularInline): per_page = 25 # More items for simple dataclass ComplexInline(StackedInline): per_page = 5 # Fewer items for complex forms
Set extra=0 for paginated inlines
When using pagination, set extra=0 to avoid empty forms:
class BookInline(TabularInline): model = Book extra = 0 # Don't show empty forms with pagination per_page = 10
Users can add new items via the “Add another” button.
Optimize queries
Always optimize your querysets for paginated inlines:
For view-heavy use cases, make most fields readonly:
class HistoryInline(TabularInline): model = OrderHistory extra = 0 per_page = 20 can_delete = False def get_readonly_fields(self, request, obj=None): return [f.name for f in self.model._meta.fields]