Configuration Options
Complete alphabetical reference of all available configuration options with defaults, accepted values, and descriptions.
Types are shown next to each setting name. Accepted values is the contract for each setting. None means the setting is left unset unless the row says otherwise.
For the mental model behind the option groups, see PowerCRUD Concepts.
Core Configuration
| Setting | Accepted values | Default | When unset | Description | Reference |
|---|---|---|---|---|---|
action_button_classes (str) |
str |
"" |
Buttons keep the selected pack's built-in classes | Additional CSS classes for the View/Edit/Delete buttons. Values are not translated between frameworks. | Template Packs |
base_template_path (str) |
non-empty str |
None (required) |
Invalid when unset; must point at your project’s base template | Template path PowerCRUD inherits from (your site chrome). There is no bundled base layout. | Setup & Core CRUD basics |
bulk_async (bool) |
True, False |
False |
Bulk actions run synchronously | Enable asynchronous processing for bulk operations. | Bulk editing (async) |
bulk_async_allow_anonymous (bool) |
True, False |
True |
Anonymous users may trigger async jobs | Require authentication for async bulk operations by setting to False. |
Bulk editing (async) |
bulk_async_backend (str) |
str |
'q2' |
Uses the django-q2 backend | Backend identifier for async processing. | Bulk editing (async) |
bulk_async_conflict_checking (bool) |
True, False |
True |
Conflict locks are validated before queuing | Toggle optimistic locking for async bulk edits. | Bulk editing (async) |
bulk_async_notification (str) |
str; common values: 'status_page', 'email', 'messages' |
'status_page' |
Users are redirected to the status page | Notification mechanism for async jobs. | Bulk editing (async) |
bulk_update_persistence_backend_config (dict) |
None or dict[str, Any] |
None |
No backend-specific config is passed | Optional config payload passed into the configured bulk update persistence backend constructor. | Bulk editing (async) |
bulk_update_persistence_backend_path (str) |
None or import path str |
None |
PowerCRUD uses the built-in bulk update implementation | Optional import path for a worker-safe bulk update persistence backend. When configured, the default sync bulk path and async bulk worker both delegate through it. | Bulk editing (async) |
bulk_delete (bool) |
True, False |
False |
Bulk delete buttons are hidden | Enable bulk delete functionality. | Bulk editing (synchronous) |
bulk_fields (list[str]) |
list[str] |
[] |
Bulk edit form is disabled | Editable model fields exposed in the bulk edit form. Non-editable fields and queryset annotation names raise a configuration error. | Bulk editing (synchronous) |
bulk_full_clean (bool) |
True, False |
True |
Each object runs full_clean() during bulk edits |
Skip expensive validation by setting to False. |
Bulk editing (synchronous) |
bulk_min_async_records (int) |
int |
20 |
Async path activates when at least 20 rows are selected | Threshold for switching from sync to async bulk operations. | Bulk editing (async) |
bulk_modal_presentation (dict) |
Partial modal_presentation mapping |
None |
Uses modal_presentation |
Portable override for the built-in Bulk Edit dialog. | Setup & Core CRUD basics |
bulk_modal_box_classes (str) |
None or str |
None |
Uses modal_box_classes |
Deprecated. Framework-specific replacement classes for the built-in Bulk Edit dialog; emits FutureWarning and is targeted for removal in v1.0. |
Deprecations |
column_alignments (dict[str, str]) |
None or dict[str, 'left' \| 'center' \| 'right'] |
None |
Rendered list body cells use the built-in type-based alignment heuristic | Override list body-cell alignment for specific rendered fields or properties by name. Unconfigured columns keep the default heuristic. | Setup & Core CRUD basics |
column_help_text (dict[str, str]) |
None or dict[str, str] |
None |
Column headers render without help icons | Add plain-text help tooltips to specific list headers by field/property name. Only configured columns show the adjacent info trigger. | Setup & Core CRUD basics |
column_sort_fields_override (dict[str, str]) |
None or dict[str, str] |
None |
Sortable list columns use their own field names, except direct relations with a concrete name field which default to field__name |
Override the queryset order_by() expression used when a visible list column header is clicked. Keys are visible column names, including queryset annotation fields; values are Django ordering expressions such as "author__name" or "customer__code". |
Setup & Core CRUD basics |
column_value_formats (dict[str, str]) |
None or dict[str, 'date' \| 'time' \| 'datetime'] |
None |
Temporal model fields use their type defaults | Override a named DateTimeField or typed temporal queryset annotation. DateField accepts only date, TimeField only time, and DateTimeField all three. Properties and annotations without an inferable temporal output_field are invalid. |
Setup & Core CRUD basics |
column_width_modes (dict[str, str]) |
None or dict[str, 'compact' \| 'auto' \| 'bounded'] |
None |
The view-wide column_width_policy decides each column |
Override the automatic or default width choice for individual fields, annotations, or configured properties. | Setup & Core CRUD basics |
column_width_policy (str) |
'bounded', 'semantic' |
'bounded' |
Uses PowerCRUD's normal general-purpose table sizing | Set to 'semantic' to choose compact widths for automatic primary keys and booleans, value-sized widths for temporal and numeric fields, and bounded widths for other columns. Queryset annotations use their declared output_field; untyped computed properties need an explicit override when they represent a short value. |
Setup & Core CRUD basics |
default_datetime_value_format (str) |
'date', 'time', 'datetime' |
'date' |
DateTimeField columns show date-only output | View-wide fallback for unconfigured DateTimeField and typed datetime-annotation list columns. Named column_value_formats entries take precedence. Set Django DATE_FORMAT, TIME_FORMAT, and DATETIME_FORMAT to control the rendered values; Django defaults apply when they are unset. |
Setup & Core CRUD basics |
default_htmx_target (str) |
str |
'#content' |
Responses target the main content container | Default HTMX target selector (ignored when HTMX is off). | Setup & Core CRUD basics |
default_filterset_fields (list[str]) |
None or list[str] |
None |
All allowed filters render immediately | Limit the initially visible filter subset while keeping the remaining allowed filters available through the built-in Add filter control. Validated against effective filter names from the bound filter form. | Filter controls |
default_list_fields (list[str]) |
None or non-empty list[str] |
None |
Uses every allowed list column as the default visible set | Optional default/reset subset for list options. Setting it also enables list options for backward compatibility. Model fields, queryset annotation fields, and properties are supported. | List Options |
detail_exclude (list[str]) |
list[str] |
[] |
Detail view mirrors the resolved detail_fields |
Remove specific fields from the detail layout. | Setup & Core CRUD basics |
detail_fields (list/str) |
None, '__all__', '__fields__', list[str] |
'__fields__' |
Inherits model fields from the list view | Model fields rendered on the detail page. Queryset annotation names are list/filter columns and are not accepted as explicit detail fields. | Setup & Core CRUD basics |
field_labels (dict[str, str]) |
None or dict[str, str] |
None |
Labels use model verbose_name metadata or raw-name fallbacks |
Override display labels for named fields/properties across list headers, list options, forms, inline editing, display-only form items, and bulk edit labels. Explicit labels render exactly. | Setup & Core CRUD basics |
detail_properties (list/str) |
None, '__all__', '__properties__', list[str] |
[] |
No properties appear on the detail page | Add computed properties to the detail view. | Setup & Core CRUD basics |
detail_properties_exclude (list[str]) |
list[str] |
[] |
All listed detail properties render | Remove specific properties from the detail page. | Setup & Core CRUD basics |
dropdown_sort_options (dict) |
dict[str, str] |
{} |
PowerCRUD orders dropdowns by name/title/... heuristics |
Explicit ordering for dropdowns in filters, forms, and bulk edit widgets. | Bulk editing (synchronous) |
exclude (list[str]) |
list[str] |
[] |
Every concrete model field is shown | Remove individual fields from the list view while keeping the rest. | Setup & Core CRUD basics |
extra_actions (list[dict \| PowerAction]) |
list[action spec] |
[] |
Only the built-in row actions render | Define extra per-row actions (URL, label, attributes). Modal actions may set partial modal_presentation, refresh_list_on_modal_close, hidden_if, disabled-state hooks, and permission affordance fields. |
Complete Example |
extra_actions_mode (str) |
'buttons', 'dropdown', 'all_dropdown' |
'dropdown' |
Built-in actions remain visible and configured extras use a kebab menu | Control row-action presentation on wider viewports. 'dropdown' keeps permitted View/Edit/Delete controls visible and moves only extras behind a kebab; 'all_dropdown' puts every permitted row action behind one kebab. On narrow viewports every mode collapses to the all-actions layout. |
Setup & Core CRUD basics |
extra_actions_dropdown_open_upward_bottom_rows (int) |
int >= 0 |
3 |
All row-action menus open downward | In either dropdown mode, open the row-action menu upward for the last N rendered rows on the current page. Set 0 to disable this behavior. |
Setup & Core CRUD basics |
extra_button_classes (str) |
str |
"" |
Extra buttons use the default button styling | Additional CSS classes shared by every entry in extra_buttons. |
Styling & Tailwind |
extra_buttons_dropdown_label (str) |
non-empty str |
"Actions" |
The list-level extra-button dropdown is labelled Actions | Override the visible and accessible trigger label used when extra_buttons_mode = "dropdown". |
Setup & Core CRUD basics |
extra_button_selection_controls_disabled (bool) |
True, False |
False |
Selection-aware extra buttons can render row selection controls | Set to True if the button uses selected rows, but this list should not show checkboxes just because of that button. Bulk edit and bulk delete still show checkboxes because they need them. |
Setup & Core CRUD basics |
extra_buttons_mode (str) |
'buttons', 'dropdown' |
'buttons' |
Extra header buttons render as visible toolbar buttons | Control how list-level extra_buttons are rendered. Use 'dropdown' to move configured extra buttons into a top toolbar Actions menu. |
Setup & Core CRUD basics |
extra_buttons (list[dict \| PowerButton]) |
list[button spec] |
[] |
No extra header buttons are shown | Add top-of-page buttons (e.g., custom actions, links). Buttons with uses_selection=True can render row selection controls even when built-in bulk edit/delete is not configured and clear the persisted selection after a successful HTMX request by default. Set clear_selection_on_success=False for read-only summary or preview buttons that should preserve selection. Modal buttons may set partial modal_presentation, refresh_list_on_modal_close, and permission affordance fields. |
Complete Example |
filter_favourites_enabled (bool) |
True, False |
False |
No saved-favourites toolbar is rendered | Enable the optional saved favourites UI for this list view when the powercrud.contrib.favourites app is installed and powercrud.urls is mounted under the powercrud namespace. |
Saved Favourites |
fields (list/str) |
None, '__all__', list[str] |
'__all__' |
All concrete model fields show in the list view | Columns displayed in the list view. Explicit lists may contain model field names and queryset annotation names. Combine with exclude. |
Setup & Core CRUD basics |
filter_null_fields_exclude (list[str]) |
list[str] |
[] |
Nullable auto-generated filters gain built-in null filtering | Opt out specific filterset_fields from automatic null-filter controls. |
Filter controls |
filter_queryset_options (dict) |
dict[str, filter spec] |
{} |
Filter dropdowns query the entire related table | Restrict or pre-filter related dropdown options per field. | Filter controls |
filterset_class (FilterSet) |
None or FilterSet subclass |
None |
A dynamic FilterSet is generated from filterset_fields |
Provide a custom FilterSet subclass for complex filtering. |
Filter controls |
filterset_fields (list[str]) |
list[str] |
[] |
No filter sidebar is rendered | Model fields or queryset annotation names to include in the auto-generated filterset. Annotation filters require an inferable output_field. |
Filter controls |
form_class (ModelForm) |
None or ModelForm subclass |
None |
PowerCRUD builds a ModelForm from form_fields |
Override the form entirely with a custom class. | Form controls |
form_fields (list/str) |
None, '__all__', '__fields__', list[str] |
None |
All editable detail_fields appear in the auto-generated form |
Editable model fields included when PowerCRUD generates the form class for you. Queryset annotation names are invalid because they are read-only. Ignored when form_class is set. |
Form controls |
form_fields_exclude (list[str]) |
list[str] |
[] |
The auto-selected form fields render untouched | Remove individual fields from the auto-generated form. Ignored when form_class is set. |
Form controls |
form_display_fields (list[str]) |
list[str] |
[] |
No display-only context block is shown above forms | Model fields to render as read-only context above update forms. Can include editable=False model fields. |
Form controls |
form_disabled_fields (list[str]) |
list[str] |
[] |
Every update-form field stays editable | Disable specific update-form inputs while keeping them visible on the form. Must reference fields present on the built form. | Form controls |
field_queryset_dependencies (dict \| None) |
None or dependency map |
None |
Select fields use their default queryset | Declarative parent/child queryset scoping shared by regular forms and inline forms. | Form controls |
hx_trigger (str/int/float/dict) |
None, scalar trigger name, or trigger map |
None |
No HX-Trigger header is sent | Custom HTMX triggers to fire after responses. | Setup & Core CRUD basics |
inline_edit_allowed (callable) |
None or predicate callable |
None |
Every row follows the standard permission checks | Optional predicate to allow/block inline editing per row. | Inline editing |
inline_edit_always_visible (bool) |
True, False |
True |
Editable cells keep a subtle always-on hint | Toggle whether inline-editable cells show a resting highlight before hover/focus. Setting this to False removes only the resting highlight; hover/focus highlighting still remains active. |
Inline editing |
inline_edit_fields (list/str) |
None, '__all__', '__fields__', list[str] |
None |
Inline editing is disabled | Editable model fields editable inline. Queryset annotation names and explicit non-editable fields raise a configuration error; after that validation, PowerCRUD still filters the list to fields present on the actual form, only rendered list columns become clickable inline cells, and the inline row reposts the rest of the full form as hidden inputs on save. | Inline editing |
inline_edit_highlight_accent (str) |
hex color #rgb or #rrggbb |
'#14b8a6' |
Inline editing uses the built-in teal accent | Accent color used to derive the inline-edit resting, hover/focus, and active-row highlight shades. Hex input only. | Inline editing |
inline_save_refresh_policy (str) |
'reset_if_filtered_out', 'keep_page', 'reset_page' |
'reset_if_filtered_out' |
Successful inline saves refresh the current list page unless the saved row falls out of the active filters | Control whether inline-save list refreshes preserve the current page query parameter or drop back to page 1. Filtering, sorting, and page_size are always preserved. |
Inline editing |
inline_preserve_required_fields (bool) |
True, False |
True |
Stock inline rows already repost non-rendered fields; this remains a fallback for custom omissions | Reuse the object’s existing values for required form fields when a custom inline POST still omits them. | Inline editing |
inline_edit_requires_perm (str) |
None or str |
None |
Inline editing shows for anyone who can edit the object | Permission codename required before showing inline controls. | Inline editing |
list_cell_link_default_open_in (str) |
'current', 'new', 'modal' |
'new' |
Omitted list-cell open_in values open in a new browser context |
Optional view-wide default opening mode for declarative and hook-backed list-cell links. If omitted, PowerCRUD assumes 'new'. Explicit per-link open_in wins. Use 'modal' when internal drill-in links should preserve the current list context, or 'current' for normal same-page anchors. |
Setup & Core CRUD basics |
list_options_enabled (bool) |
True, False, None |
None |
No column chooser unless default_list_fields is set |
Enable the session-backed Cols control without narrowing the default visible columns. Use with default_list_fields when the reset/default state should be a subset. Set False to explicitly disable list options on a view. |
List Options |
list_toolbar_width_policy (str) |
'container', 'table' |
'table' |
Toolbar follows the rendered table width | Set to 'container' to keep list controls independent of a compact table and clamp them to the PowerCRUD list container. |
Setup & Core CRUD basics |
list_toolbar_alignment (str) |
'adjacent', 'split' |
'split' |
View controls move to logical end when space permits | Set to 'adjacent' to keep view controls beside action controls with a small group gap. Both modes wrap naturally at narrow widths. |
Setup & Core CRUD basics |
link_fields (dict[str, str \| dict]) |
None or mapping of rendered field/property name to a view_name string or a dict with exactly one of view_name / url, plus optional pk_attr / open_in / modal_presentation |
None |
List cells render as plain text/value output | Make selected rendered list cells clickable. String shorthand uses the named view plus a default pk source (<field>_id for relation fields, row pk otherwise). Dict form may reverse a Django view_name or use a static url. Omitted open_in values use list_cell_link_default_open_in, whose own omitted default is "new"; explicit values may be "current", "new", or "modal". Modal links may set partial modal_presentation; the legacy modal_box_classes is deprecated. Inline-editable cells are never linked. |
Setup & Core CRUD basics |
list_cell_tooltip_fields (dict[str, str \| dict]) |
None, dict[str, str], dict[str, {"hook": str, "mode": "eager" \| "lazy"}], or deprecated list[str] |
None |
No semantic list-cell tooltips are rendered | Map rendered list fields/properties to row-specific tooltip hook methods. String values are eager. Rich dict values may set mode="lazy" so PowerCRUD skips tooltip hook work during list render and resolves content only when the cell tooltip is hovered or focused. PowerCRUD only evaluates configured names that are actually visible in the current list and silently ignores configured names that are not rendered. Hook-backed semantic cell tooltip text may include newline characters for multiline display. The legacy list form is deprecated and eager-only. |
Lazy Evaluation |
m2m_filter_and_logic (bool) |
True, False |
False |
Multi-select filters use OR logic | Switch ManyToMany filters to AND logic. | Filter controls |
modal_presentation (dict) |
Partial semantic modal mapping | Portable defaults | Uses the canonical centered, viewport-bounded, body-scrolling dialog | Portable control of size, exact maximum width/height, scroll ownership, fullscreen, and vertical alignment. | Setup & Core CRUD basics |
modal_body_classes (str) |
None or str |
DaisyUI legacy default | Legacy class fallback | Deprecated. Framework-specific classes for the modal content wrapper; emits FutureWarning and is targeted for removal in v1.0. |
Deprecations |
modal_box_classes (str) |
None or str |
DaisyUI legacy default | Legacy class fallback | Deprecated. Framework-specific modal-box classes; emits FutureWarning and is targeted for removal in v1.0. |
Deprecations |
modal_classes (str) |
None or str |
'modal' |
Legacy class fallback | Deprecated. Framework-specific modal-shell classes; emits FutureWarning and is targeted for removal in v1.0. |
Deprecations |
modal_id (str) |
None or str |
None |
Falls back to 'powercrudBaseModal' |
Page-unique DOM id assigned to PowerCRUD's rendered modal shell (without #). It does not select an application-owned modal. |
Setup & Core CRUD basics |
modal_target (str) |
None or str |
None |
Falls back to 'powercrudModalContent' |
Page-unique DOM id assigned to PowerCRUD's rendered modal content host (without #). It does not select an application-owned target. |
Setup & Core CRUD basics |
model (Model) |
Django model class | Required | PowerCRUD cannot run without a model | Django model class for the CRUD view. | Setup & Core CRUD basics |
namespace (str) |
None or str |
None |
URL names are generated without a namespace | Set to match app_name when including the view in namespaced URLs. |
Setup & Core CRUD basics |
page_size_all_enabled (bool) |
True, False |
True |
The page-size selector includes All, and ?page_size=all disables pagination |
Set False to remove All from the selector and make direct ?page_size=all requests fall back to paginate_by. Cannot be False when paginate_by = None. |
Setup & Core CRUD basics |
page_size_options (list[int]) |
None or non-empty list[int] |
None |
Selector uses legacy numeric choices 5/10/25/50/100; direct positive integer ?page_size= values are accepted |
Explicit finite page-size choices for the selector. When set, direct ?page_size= values must be in this list or they fall back to paginate_by. Must include paginate_by when pagination has a finite default. |
Setup & Core CRUD basics |
paginate_by (int) |
None or int |
25 |
Lists render 25 rows per page | Default page size for list views. Set None on a view to render every record by default, which requires page_size_all_enabled = True. |
Setup & Core CRUD basics |
power_fields (list) |
None or list[PowerField \| PowerOverride] |
None |
Base Field Intent attributes are used directly | Structured declarations for Field Intent. A PowerField view must not mix base Field Intent attributes in the same inheritance chain. | PowerField Reference |
properties (list/str) |
None, '__all__', list[str] |
[] |
No computed properties show in the list view | Computed properties to display alongside fields. | Setup & Core CRUD basics |
properties_exclude (list[str]) |
list[str] |
[] |
Every listed property renders | Remove individual properties from the list view. | Setup & Core CRUD basics |
row_actions_column_position (str) |
'start', 'end' |
'end' |
The Actions column remains after the data columns | Place the Actions column at the logical start or end of list tables. In LTR layouts start is left and end is right; RTL reverses those physical edges. When selection controls are present, their checkbox column remains the outermost start column. | Setup & Core CRUD basics |
row_actions_column_sticky (bool) |
True, False |
True |
The Actions column remains pinned during horizontal table scrolling | Pin the Actions header and display/inline action cells to their configured logical edge during horizontal table scrolling. This does not fix them vertically or change the floating More menu. |
Styling & Tailwind |
searchable_selects (bool) |
None, True, False |
True |
Select widgets render as native <select> controls |
Enable Tom Select enhancement for eligible select fields in regular forms, inline editing, bulk edit forms, and filter forms. | Form controls |
show_bulk_selection_meta (bool) |
True, False |
True |
Bulk-selection metadata actions appear above the table when a selection exists | Control the contextual bulk-selection action row independently of show_record_count. |
Bulk editing (synchronous) |
show_record_count (bool) |
True, False |
False |
No results-count metadata is shown above the table | Display a small status line above the list table showing the total filtered queryset size, or the current page slice plus total when pagination is enabled. | Setup & Core CRUD basics |
table_classes (str) |
str |
"" |
Tables use the selected pack's default classes | Additional classes applied to the main table element. Values are not translated between frameworks. | Template Packs |
table_header_min_wrap_width (int) |
None or int |
None |
Matches table_max_col_width |
Minimum width (in ch) before header labels wrap. |
Styling & Tailwind |
table_max_col_width (int) |
None or positive int |
None |
Columns clamp at 25ch |
Maximum column width (in ch) for list and inline edit layouts. |
Styling & Tailwind |
table_max_height (int) |
int from 0 to 100 |
70 |
Table height is 70% of remaining viewport | Percentage of remaining viewport height allocated to the table. | Styling & Tailwind |
table_pixel_height_other_page_elements (int/float) |
non-negative int or float |
0 |
No extra offset is subtracted | Pixels reserved for other fixed-height elements (e.g., navbars). | Styling & Tailwind |
templates_path (str) |
str |
None |
Uses the selected pack's template namespace | Explicit base directory that replaces the selected pack namespace. Use only when your project owns a complete template root. | Template Packs |
template_override_path (str) |
str |
None |
No project-level template root | Application template root tried after model-specific files and before templates_path. Missing files fall back to the selected pack unless template_override_complete is enabled. |
Template Packs |
template_override_complete (bool) |
True, False |
False |
Direct nested includes use templates_path |
Set to True only for a complete app-level --all copy so direct nested includes use template_override_path too. |
Template Packs |
url_base (str) |
str |
Model name | Defaults to the model’s lowercase name | URL slug used when generating routes (e.g., project-list). |
Setup & Core CRUD basics |
use_crispy (bool) |
None, True, False |
None |
Auto-detects: True when crispy_forms is installed |
Toggle Crispy Forms rendering for generated forms. Configure the compatible Crispy integration and CRISPY_TEMPLATE_PACK in your application. |
Selecting and configuring |
use_htmx (bool) |
None, True, False |
None |
HTMX is disabled | Enable HTMX responses (modals, inline updates, partial refreshes). | Setup & Core CRUD basics |
use_modal (bool) |
None, True, False |
None |
Modals stay disabled | Enable HTMX-driven modal forms (requires use_htmx = True). |
Setup & Core CRUD basics |
view_help (dict) |
None or {"summary": str, "details": str, "default_open": bool, "color": str, "min_width": str} |
None |
No collapsed screen help is shown | Render optional collapsed screen-level help below view_instructions and above the list toolbar. Content is escaped plain text; blank lines in details create paragraphs. Optional color accepts the portable semantic tokens base, primary, secondary, accent, neutral, info, success, warning, error, or hex. Optional min_width overrides the view default. |
Setup & Core CRUD basics |
view_help_default_color (str) |
portable semantic colour or hex colour | base |
Collapsed screen help uses the quiet base colour | Default colour theme for view_help when the help dict does not provide color. Semantic and hex colours are rendered as subtle pack-native tints. |
Setup & Core CRUD basics |
view_help_min_width (str) |
CSS size using px, rem, em, ch, or % |
40rem |
Collapsed screen help is at least 40rem wide when space allows |
Minimum width floor for table-aligned screen help. The help block still clamps to the surrounding container. | Setup & Core CRUD basics |
view_instructions (str) |
None or non-empty str |
None |
No helper text is shown under the list heading | Render plain-text helper copy directly beneath the visible list-page heading. Content is escaped and does not accept HTML. | Setup & Core CRUD basics |
view_title (str) |
None or non-empty str |
None |
The visible list heading uses verbose_name_plural |
Override the visible list-page heading without changing model metadata or other singular/plural UI copy. | Setup & Core CRUD basics |
Settings Configuration
All of the following keys live inside the optional POWERCRUD_SETTINGS dict in your Django settings. Every entry has a default; you only override what you need.
| Setting | Accepted values | Default | When unset | Description | Reference |
|---|---|---|---|---|---|
ASYNC_ENABLED (bool) |
True, False |
False |
Async helpers remain inactive | Master toggle for async features. | Async Manager |
BULK_MAX_SELECTED_RECORDS (int) |
positive int |
1000 |
Bulk selections can grow to 1000 rows before PowerCRUD stops adding more matching records | Global cap for the synchronous bulk-selection pipeline, including queryset-wide Select all ... and capped Add ... more from ... metadata actions. Usually keep this at or below Django's DATA_UPLOAD_MAX_NUMBER_FIELDS. |
Bulk editing (synchronous) |
CACHE_NAME (str) |
str |
'default' |
Uses Django’s default cache backend | Cache alias used for conflict locks and progress entries. | Async Manager |
CONFLICT_TTL (int) |
int |
3600 |
Locks expire after one hour | Cache TTL (seconds) for conflict lock entries. | Async Manager |
PROGRESS_TTL (int) |
int |
7200 |
Progress data expires after two hours | Cache TTL (seconds) for async progress entries. | Async Manager |
CLEANUP_GRACE_PERIOD (int) |
int |
86400 |
Completed tasks are eligible for cleanup after 24h | Grace period before scheduled cleanup reclaims finished tasks. | Async Manager |
FILTER_FAVOURITE_USER_RESOLVER (str or callable) |
None, callable, or dotted import path str |
None |
Saved favourites are owned by request.user |
Optional resolver for the user who owns saved filter favourites. The resolver receives the request and should return the user used by favourites toolbar, save, apply, update, and delete behavior. | Saved Favourites |
MAX_TASK_DURATION (int) |
int |
3600 |
Tasks longer than an hour are treated as stuck | Threshold for flagging slow async jobs. | Async Manager |
CLEANUP_SCHEDULE_INTERVAL (int) |
int |
300 |
Cleanup jobs should run roughly every 5 minutes | Suggested cadence (seconds) for any periodic cleanup runner. | Async Manager |
POWERCRUD_TEMPLATE_PACK (str) |
absent, built-in alias daisyui, or template-pack declaration path |
absent | Selects the supported DaisyUI default | Select the complete template pack at process startup. Use powercrud.contrib.bootstrap5:template_pack for Bootstrap 5. |
Selecting and configuring |
POWERCRUD_CSS_FRAMEWORK (str) |
str; bundled default: 'daisyUI' |
'daisyUI' |
Retains the compatible DaisyUI styling path | Legacy CSS-framework compatibility setting. It does not select an optional template pack such as Bootstrap. | Selecting and configuring |
TAILWIND_SAFELIST_JSON_LOC (str) |
str |
'.' |
Uses the current directory as the default output location | File path for Tailwind safelist output (used by management commands). | Styling & Tailwind |
Filter controls
Fine-tune what users can filter and how options are presented by combining filterset_fields, default_filterset_fields, filter_queryset_options, dropdown_sort_options, filter_null_fields_exclude, and m2m_filter_and_logic.
filterset_fields vs filterset_class
filterset_fields and filterset_class are alternative strategies.
If you set filterset_class, it takes precedence and PowerCRUD does not auto-generate filters from filterset_fields.
These settings only shape the auto-generated filterset_fields path:
filter_queryset_optionsfilter_null_fields_excludem2m_filter_and_logic- filter-side
dropdown_sort_options
These behaviors still apply to both generated and custom filtersets after the filterset exists:
default_filterset_fieldssearchable_selects- HTMX widget attrs when
use_htmx = Trueand the custom filterset exposessetup_htmx_attrs()
For custom filtersets, the recommended pattern is still to subclass HTMXFilterSetMixin when you want reactive filtering.
default_filterset_fields controls which allowed filters are visible on first render.
- Leave it unset to keep the current behavior and show every allowed filter immediately.
- Set it to a subset to keep the remaining allowed filters hidden behind the Add filter control.
- PowerCRUD validates it against the effective filter names from the bound filter form, not only against raw model field names.
- Hidden optional filters become visible automatically when they carry an active value in the URL.
- Visible optional filters persist through the reserved
visible_filtersquery parameter until the user removes them explicitly.
Nullable auto-generated filters behave differently by field type:
- Nullable
ForeignKeyandOneToOneFieldfilters keep a single dropdown and add anEmpty onlyoption near the top. - Nullable scalar filters such as
CharField,TextField,DateField,TimeField,IntegerField,DecimalField,FloatField, andBooleanFieldgain a separate companion... is emptyboolean select. - Companion null controls are rendered immediately after their parent auto-generated filter field in the form.
Auto-generated model fields with choices render as dropdown filters and match the selected value exactly. Text fields without choices use icontains by default. There is no separate declarative setting to change that lookup expression field by field; use filterset_class when you need custom lookup expressions.
Queryset annotation filters
Generated filters may also target queryset annotation names:
from django.db.models import BooleanField, Case, Value, When
class BookQueueView(PowerCRUDMixin, CRUDView):
model = Book
def get_queryset(self):
"""Attach the public annotation name used by PowerCRUD config."""
return super().get_queryset().annotate(
long_book=Case(
When(pages__gte=400, then=Value(True)),
default=Value(False),
output_field=BooleanField(),
)
)
fields = ["title", "author", "pages", "long_book"]
filterset_fields = ["author", "long_book"]
Rules:
- The name in
fieldsandfilterset_fieldsmust match the publicannotate(...)keyword. - Use
output_fieldonCase,Value, and complex expressions so PowerCRUD can infer the generated filter type. - Annotation fields are read-only list/filter/sort columns. Do not put them in
form_fields,inline_edit_fields, orbulk_fields. - If you set
filterset_class, it takes precedence and PowerCRUD does not auto-generate annotation filters.
filter_null_fields_exclude always matches the original field names listed in filterset_fields.
- Use
["birth_date"], not["birth_date__isnull"]. - Excluding a nullable scalar field suppresses the generated companion
... is emptycontrol. - Excluding a nullable relation field suppresses the merged
Empty onlyoption.
Example:
filterset_fields = ["owner", "published_date", "status"]
default_filterset_fields = ["owner"]
filter_null_fields_exclude = ["status"]
In that configuration, owner stays visible by default, while published_date and status remain allowed but optional. owner keeps one dropdown with Empty only, published_date gains a separate Published date is empty companion filter when added, and status gets no built-in null helper.
If you want title to use iexact or startswith instead of the generated icontains behavior, move that filter into a custom filterset_class.
Start with the Filtering & sorting walkthrough and the dropdown guidance in Bulk editing (synchronous).
Form controls
Override or refine the automatically generated forms with form_class, form_fields, form_fields_exclude, form_display_fields, form_disabled_fields, and field_queryset_dependencies, and enable Crispy Forms support via use_crispy. See the field/detail setup examples in Setup & Core CRUD basics, the dedicated Forms guide, and the complete view example in reference/complete_example.md.
Relationship Between form_class and PowerCRUD Form Parameters
form_class overrides PowerCRUD form generation.
If you set form_class, PowerCRUD does not use form_fields or form_fields_exclude to decide which editable fields appear on the form. Those two parameters are for auto-generated forms only.
PowerCRUD still applies its runtime form behavior after the custom form is built, including form_disabled_fields, form_display_fields, field_queryset_dependencies, dropdown_sort_options, searchable_selects, and use_crispy.
The selected pack may also present a model-backed visible field that still uses Django's silent default widget. A declared field, Meta.widgets entry, runtime widget replacement, non-model field, or hidden field remains application-owned. See Forms.
form_display_fields and form_disabled_fields solve two different problems:
form_display_fieldsadds a separate read-onlyContextblock above update forms. Use it for contextual model data, includingeditable=Falsefields.form_disabled_fieldskeeps a real form input visible but locked on update forms. Because PowerCRUD uses Django field disabling, submitted tampering is ignored and the existing instance value is preserved. This setting does not lock the same field in create forms or inline editing.
Dependent queryset scoping
Use field_queryset_dependencies for straightforward cases where one selectable child field should be filtered from another form field, or where a queryset-backed field should always be restricted to a fixed subset.
Example:
field_queryset_dependencies = {
"genres": {
"static_filters": {"is_active": True},
"depends_on": ["author"],
"filter_by": {"authors": "author"},
"order_by": "name",
"empty_behavior": "none",
}
}
Supported keys:
static_filtersFixed queryset lookups that always apply to the field across regular forms, inline forms, and bulk edit dropdowns.depends_onParent form fields whose values drive the child queryset.filter_byMapping of child queryset lookups to parent form field names.order_byOptional ordering applied after filtering.empty_behavior"none"hides all child choices until the parent value is available."all"leaves the queryset unfiltered when the parent value is empty.
Notes:
- Static queryset rules apply to regular create/update forms, inline forms, and bulk edit dropdowns.
- Dynamic dependency rules apply to regular create/update forms and inline forms through the same form pipeline.
- Overriding
get_bulk_choices_for_field()bypasses declarative static queryset rules for bulk. - PowerCRUD resolves parent values from bound form data first, then the current instance, then any initial form values.
- Keep this for simple equality-style filtering on queryset-backed form fields. For complex business rules, continue using a custom
form_classor view override. filter_bymaps child queryset lookups to parent form field names. The left-hand side is the lookup used against the child field queryset, while the right-hand side is the parent form field name.
Common mental model:
field_queryset_dependencies = {
"child_field": {
"static_filters": {"is_active": True},
"depends_on": ["parent_field"],
"filter_by": {"child_queryset_lookup": "parent_field"},
}
}
That reads as: “restrict child_field choices first by any fixed filters, then by child_queryset_lookup=<value of parent_field> when a parent-driven rule exists”.
Worked examples:
field_queryset_dependencies = {
"genres": {
"depends_on": ["author"],
"filter_by": {"authors": "author"},
}
}
field_queryset_dependencies = {
"cmms_asset": {
"depends_on": ["cmms_property_asset_type_override"],
"filter_by": {
"property_asset_type_override": "cmms_property_asset_type_override",
},
}
}
For a full explanation of filter_by, migration from old inline-only configs, and regular-vs-inline behaviour, see Forms.
Header buttons
Use extra_buttons for list-level actions above the table.
extra_buttons_mode controls whether configured list-level buttons render
directly in the toolbar or move into a compact overflow menu:
'buttons'keeps the default behavior and renders every configured extra button visibly.'dropdown'keeps built-in actions such as Create outside the overflow and moves only configuredextra_buttonsinto a top toolbar Actions menu.
Set extra_buttons_dropdown_label to change that menu's visible and accessible
trigger text for a particular view. The label must be a non-empty string and is
used only when extra_buttons_mode = "dropdown":
Selection-aware buttons can opt into the current persisted PowerCRUD selection:
extra_buttons_mode = "dropdown"
extra_buttons = [
{
"url_name": "projects:summary-help",
"text": "Summary Help",
"display_modal": True,
"refresh_list_on_modal_close": True,
"modal_presentation": {"size": "wide"},
},
{
"url_name": "projects:selected-summary",
"text": "Selected Summary",
"display_modal": True,
"uses_selection": True,
"selection_min_count": 1,
"selection_min_behavior": "disable",
"selection_min_reason": "Select at least one row first.",
"permission_check": "can_view_project_report",
"permission_behavior": "hide",
},
]
Notes:
uses_selectiondefaults toFalse.selection_min_countdefaults to0.selection_min_behavioraccepts'allow'or'disable'and defaults to'allow'.modal_presentationis only used whendisplay_modal=True; it merges with the view presentation while that button's modal is open. Omit it when the button should use the default dialog.refresh_list_on_modal_closeis only used whendisplay_modal=True; preferHX-Trigger: {"refreshTable": true}when the endpoint knows it changed data.- When
uses_selection=True, the button endpoint should use the current persisted PowerCRUD selection. clear_selection_on_successdefaults toTruewhenuses_selection=TrueandFalseotherwise. PowerCRUD clears the persisted selection after the button's successful HTMX request completes; failed requests leave the selection intact. Setclear_selection_on_success=Falsefor summary or preview buttons that should preserve the user's selection.- A selection-aware
extra_buttonsentry can render row selection controls even whenbulk_fields = []andbulk_delete = False. - Set
extra_button_selection_controls_disabled = Trueif the button uses selected rows, but this list should not show checkboxes just because of that button. - This is mainly useful when the selected rows come from somewhere else, or when the page has its own custom way to choose rows. Bulk edit and bulk delete still show checkboxes because they need them.
permissionorpermission_checkhides or disables the button before selection-state checks run.permission_behaviordefaults to"hide".- The endpoint should still validate selection size, permissions, and lock rules server-side.
Parameter Guide
| Parameter | Type | What it does |
|---|---|---|
url_name |
str |
Django URL name for the endpoint called by the header button. |
text |
str |
Visible label rendered on the button. |
button_class |
str |
Framework-specific button styling class such as btn-primary. |
needs_pk |
bool |
Should usually stay False for header buttons because they are not tied to a single row. |
display_modal |
bool |
Opens the response in the standard modal target when True. |
modal_presentation |
dict |
Portable per-button modal override. It accepts the documented size, maximum dimension, scroll, fullscreen, and alignment keys. |
refresh_list_on_modal_close |
bool |
Refreshes the current list partial when this modal button's dialog closes. Defaults to False; ignored unless display_modal=True. |
htmx_target |
str |
HTMX target element to update for non-modal or custom-target flows. |
extra_attrs |
str |
Raw HTML attributes appended to the button element. |
extra_class_attrs |
str |
Additional CSS classes appended after the standard button classes. |
uses_selection |
bool |
Declares that the endpoint should read the current persisted PowerCRUD selection. |
clear_selection_on_success |
bool |
Clears the persisted selection after a successful HTMX request from a selection-aware button. Defaults to True when uses_selection=True, otherwise False; ignored unless uses_selection=True. |
selection_min_count |
int |
Minimum selected-row count required before the button is considered ready. |
selection_min_behavior |
'allow' \| 'disable' |
Controls whether the button stays clickable or becomes disabled when the selected count is below selection_min_count. |
selection_min_reason |
str |
Tooltip/help text shown when a selection-aware header button is disabled. |
permission |
str |
Django permission string resolved through has_power_permission(permission, request, obj=None). |
permission_check |
str |
Named view method with signature permission_check(request, obj=None). |
permission_behavior |
'hide' \| 'disable' |
Controls whether permission failure removes the button or renders it disabled. Defaults to 'hide'. |
permission_denied_reason |
str |
Tooltip/help text used only when permission_behavior = 'disable'. |
Row actions
Use extra_actions to add per-row actions beyond the built-in View, Edit, and Delete links. Entries may be Base API dictionaries or PowerAction declarations from powercrud.actions.
extra_actions_mode controls how those extra row actions are displayed:
'buttons'keeps compact built-in icon controls visible and renders configured extra actions as labelled buttons.'dropdown'keeps the built-in icon controls visible and moves onlyextra_actionsbehind a neutral vertical-ellipsis trigger whose accessible name is More actions.'all_dropdown'replaces the visible row controls with one neutral vertical-ellipsis Actions trigger. Its labelled menu order is View, Edit, configured extras in declaration order, then Delete last.
Below 640px, the first-party packs collapse all three modes to the all_dropdown presentation. The single Actions kebab contains every permitted native and configured action in canonical order. This is a responsive default rather than another configuration value; inline Save and Cancel remain visible while editing.
The all-actions trigger and its tooltip have the accessible name Actions. The table's visual Actions heading is omitted in this compact mode, while a screen-reader-only heading preserves the column name. Inline Save and Cancel remain visible while a row is being edited.
The action column itself has two independent layout settings:
position is logical rather than physical, so it follows LTR/RTL direction. Selection checkboxes always remain the outermost start column; start-positioned actions follow them. Stickiness applies only while the table scrolls horizontally and is carried through the header, normal rows, inline edit controls, and HTMX-returned replacement rows. The default combination is "end" plus True.
Example:
extra_actions_mode = "dropdown"
extra_actions_dropdown_open_upward_bottom_rows = 3
extra_actions = [
{
"url_name": "sample:author-detail",
"text": "View Again",
"needs_pk": True,
"display_modal": True,
"permission_check": "can_view_author_again",
"permission_behavior": "hide",
"hidden_if": "should_hide_view_again",
"hidden_if_mode": "lazy",
"disabled_state": "get_view_again_disabled_state",
"disabled_state_mode": "lazy",
"refresh_list_on_modal_close": True,
"modal_presentation": {"size": "extra_wide"},
},
]
Notes:
- The default is
'dropdown': built-in actions remain visible while configured extras move behind the kebab. Set'buttons'to restore the previous wider-screen presentation. extra_actions_modecontrols row-action presentation only; it does not affect top-of-pageextra_buttons.- In either dropdown mode, configured
button_classvalues do not colour menu entries. They still apply to visible configured extras in'buttons'mode. icon_svgaccepts trusted inline SVG markup for a configured action. Define it as a named application-source constant and never derive it from request, database, or other untrusted data.icon_onlydefaults toFalse, requiresicon_svg, and affects direct buttons only; dropdown entries always retain their visible label.- The first-party packs render View, Edit, and both kebab scopes as quiet neutral controls. Delete alone retains restrained destructive colour. Menus use neutral rows, reserve an icon gutter only when at least one currently rendered action has an icon, and add a divider before Delete only when another visible item precedes it.
- Selection checkboxes are a system column pinned to logical start by default; this is not separately parameterised. Sticky logical-start actions sit immediately after selection, while sticky logical-end actions remain pinned at the opposite edge.
- To restore the previous scrolling action column, set
row_actions_column_sticky = False. - Permission-hidden standard actions are omitted. Disabled reasons, modal behavior, HTMX behavior, history, guards, lazy state, and refresh-on-close metadata are preserved.
extra_actions_dropdown_open_upward_bottom_rowscounts from the bottom of the currently rendered rows after filtering and pagination.- Set
extra_actions_dropdown_open_upward_bottom_rows = 0to keep every dropdown opening downward. modal_presentationis only used whendisplay_modal=True; it merges with the view presentation while this row action's modal is open.refresh_list_on_modal_closeis only used whendisplay_modal=True; preferHX-Trigger: {"refreshTable": true}when the endpoint knows it changed data.hidden_ifis an optional view method name with signature(obj, request) -> bool. ReturnTrueto omit the action for that row. Hidden actions are removed before disabled hooks are evaluated.- Set
hidden_if_mode = "lazy"only inextra_actions_mode = "dropdown"or"all_dropdown"when the row relevance check is expensive and should be resolved when the row menu opens. Button-mode actions keep eager hidden-if evaluation. disabled_stateis a single-hook alternative todisabled_if/disabled_reason. Return a non-empty string to disable the action and show that string as the reason; returnNone,False, or an empty string to keep it enabled.- Set
disabled_state_mode = "lazy"only inextra_actions_mode = "dropdown"or"all_dropdown"when the disabled reason is expensive to calculate and should be resolved when the row menu opens. Button-mode actions keep eager disabled-state evaluation. permissionorpermission_checkhides or disables the action beforehidden_ifanddisabled_staterun.permission_behaviordefaults to"hide".disabled_ifanddisabled_reasonare deprecated view method names used to disable a row action based on the current object and request. Usedisabled_stateinstead.- Do not combine
disabled_statewithdisabled_ifordisabled_reasonon the same action. - Use
hidden_ifwhen an action is not applicable for a row. Usedisabled_statewhen the action is applicable but unavailable and needs an explanatory reason. lock_sensitiveremains available when an action should also disable under PowerCRUD's existing lock/blocked-row state.
Parameter Guide
| Parameter | Type | What it does |
|---|---|---|
url_name |
str |
Django URL name for the per-row endpoint that the action should call. |
text |
str |
Visible label for the action button or dropdown entry. |
needs_pk |
bool |
Usually True so the row primary key is included in the URL. |
button_class |
str |
Styling class used when the action renders as a visible button. |
icon_svg |
str |
Trusted inline SVG markup. Define it in application source code; never derive it from request, database, or other untrusted data. |
icon_only |
bool |
Defaults to False. Renders only the icon in direct button mode and requires icon_svg; dropdown entries always retain their text. |
display_modal |
bool |
Opens the response in the standard modal target when True. |
modal_presentation |
dict |
Portable per-action modal override. It accepts the documented size, maximum dimension, scroll, fullscreen, and alignment keys. |
refresh_list_on_modal_close |
bool |
Refreshes the current list partial when this modal action's dialog closes. Defaults to False; ignored unless display_modal=True. |
htmx_target |
str |
HTMX target element to update for non-modal or custom-target flows. |
hx_post |
bool |
Sends the action as an HTMX POST instead of the default GET when True. |
lock_sensitive |
bool |
Disables the action automatically when PowerCRUD marks the row as blocked by its existing lock logic. |
hidden_if |
str |
Name of a view method with signature (obj, request) -> bool that decides whether the action should be omitted for that row. |
hidden_if_mode |
'eager' \| 'lazy' |
Defaults to 'eager'. Use 'lazy' with either dropdown mode to resolve hidden_if when the row menu opens. |
disabled_state |
str |
Name of a view method with signature (obj, request) -> str \| None \| bool that returns a disabled reason string, or a falsey enabled value. |
disabled_state_mode |
'eager' \| 'lazy' |
Defaults to 'eager'. Use 'lazy' with either dropdown mode to resolve disabled_state when the row menu opens. |
disabled_if |
str |
Deprecated. Name of a view method with signature (obj, request) -> bool that decides whether the action is disabled for that row. Use disabled_state instead. |
disabled_reason |
str |
Deprecated. Name of a view method with signature (obj, request) -> str \| None that returns the disabled tooltip/help text. Use disabled_state instead. |
permission |
str |
Django permission string resolved through has_power_permission(permission, request, obj=obj). |
permission_check |
str |
Named view method with signature permission_check(request, obj=None). |
permission_behavior |
'hide' \| 'disable' |
Controls whether permission failure removes the action or renders it disabled. Defaults to 'hide'. |
permission_denied_reason |
str |
Tooltip/help text used only when permission_behavior = 'disable'. |
See Permission-Aware Affordances for built-in Create/Detail/Edit/Delete permission hooks and backend enforcement boundaries.
Searchable select enhancement
PowerCRUD enhances eligible select dropdowns with Tom Select when searchable_selects = True (default).
- Applies to regular create/update forms, inline row forms, bulk edit form selects, and filter form selects.
- Single-select fields are enhanced as searchable dropdowns.
- Inline single-selects focus when their row enters edit mode, but the dropdown stays closed until the user clicks or types.
- Multi-select fields use the selected pack's standard variant on normal forms, filters, and bulk forms, and its compact variant inline.
- Standard and compact multiselects keep selected options visible with checked state, allow click-to-toggle while open, and provide clear-all.
- Boolean-style selects remain native controls.
- Preserves normal Django single- and multi-value POST semantics through the underlying
<select>. - The selected pack owns enhancement presentation and styling; application enable/disable intent remains authoritative.
See Forms, Inline editing, Filtering, and Bulk editing for surface-specific behaviour.
Per-field opt-out is available via a view hook:
class BookCRUDView(PowerCRUDMixin, CRUDView):
searchable_selects = True
def get_searchable_select_enabled_for_field(
self, field_name: str, bound_field=None
) -> bool:
return field_name != "author"
Inline dependency controls
Use field_queryset_dependencies as the primary declaration when one inline field needs another field to be refreshed in the same row. PowerCRUD derives inline dependency wiring from that shared config automatically.
Example:
field_queryset_dependencies = {
"genres": {
"depends_on": ["author"],
"filter_by": {"authors": "author"},
}
}
Notes:
- The child field must also be present in
inline_edit_fields. - Parent fields listed in
depends_onmust be inline-editable too. - PowerCRUD handles the frontend refresh, widget swap, and child queryset restriction when the dependency is declared in
field_queryset_dependencies. - PowerCRUD uses the standard
...-inline-dependencyendpoint automatically. - Older inline-only dependency config is ignored. Move any remaining business rules into
field_queryset_dependencies.
Migration sketch:
field_queryset_dependencies = {
"cmms_asset": {
"depends_on": ["cmms_property_asset_type_override"],
"filter_by": {
"property_asset_type_override": "cmms_property_asset_type_override",
},
}
}
See Forms for a fuller worked example.
Notes
- Required settings: Only
modelandbase_template_pathare required. - Auto-detection:
use_crispyauto-detects whethercrispy_formsis installed; everything else is opt-in. - Dependencies: Bulk operations require both
use_htmx = Trueanduse_modal = True. - Detail permissions: Override
has_power_detail_permission(request, obj)when the current user should not see the built-in Detail/View row action or call the PowerCRUD-owned detail endpoint. - Bulk permissions:
bulk_fieldsandbulk_deleteconfigure the operation surface. Overridehas_power_bulk_update_permission(request)orhas_power_bulk_delete_permission(request)when the current user should not see or call those PowerCRUD-owned bulk operations. - Duplicate entries: Supported list-style config options quietly remove duplicates and keep the first occurrence.
- Field shortcuts: Use
'__all__'for all fields,'__fields__'to reference thefieldssetting. - Property shortcuts: Use
'__all__'for all properties,'__properties__'to reference thepropertiessetting.