FAQ
How to template context buttons
Every context button is rendered through a Django template.
By default that template is the theme's crud_views/tags/context_action.html, configurable
project-wide via the CRUD_VIEWS_CONTEXT_BUTTON_TEMPLATE setting.
A ContextButton can override the template for that button only with two fields:
| Field | Type | Description |
|---|---|---|
template |
str \| None |
Path to a Django template for the whole button |
template_code |
str \| None |
Inline Django template string for the whole button |
template_code takes precedence over template; if neither is set, the
CRUD_VIEWS_CONTEXT_BUTTON_TEMPLATE default is used.
!!! note
These template the whole button. The existing label_template /
label_template_code fields only template the button's label inside the default
button markup.
The button template is rendered with the resolved button context, which includes:
cv_url— the target URLcv_key— the action keycv_action_label— the rendered labelcv_icon_action— the icon CSS classcv_access—Truewhen the user may access the targetcv_action_enabled—Falsehides the buttoncv_is_active—Truewhen the button points at the current view
Give a button a different shape in one view
Define a variant button in the viewset with its own template, then reference it only from the view that needs the different shape:
from crud_views.lib.viewset import ViewSet, context_buttons_default
from crud_views.lib.view import ContextButton
from crud_views.lib.views import DetailViewPermissionRequired, ListViewPermissionRequired
cv_author = ViewSet(
model=Author,
name="author",
context_buttons=context_buttons_default() + [
# the standard edit button, plus a variant with a custom template
ContextButton(key="edit", key_target="update"),
ContextButton(
key="edit_detail",
key_target="update",
template_code=(
'<a href="{{ cv_url }}" class="btn btn-primary btn-lg" cv-key="{{ cv_key }}">'
'<i class="{{ cv_icon_action }}"></i> {{ cv_action_label }}</a>'
),
),
],
)
class AuthorListView(ListViewPermissionRequired):
cv_viewset = cv_author
cv_context_actions = ["edit", "delete"] # default-shaped edit button
class AuthorDetailView(DetailViewPermissionRequired):
cv_viewset = cv_author
cv_context_actions = ["edit_detail", "delete"] # custom-shaped edit button
To change the layout of all context buttons project-wide, override
crud_views/tags/context_action.html in your project's templates, or point
CRUD_VIEWS_CONTEXT_BUTTON_TEMPLATE at your own template.
I need to render a context button manually in a template
Use the cv_context_button tag to place a single button anywhere in your own layout,
referenced by its key:
{% load crud_views %}
<div class="my-toolbar">
{% cv_context_button "edit_detail" %}
{% cv_context_button "delete" %}
</div>
The object defaults to the view's current object, so you don't normally pass it. To target a different object explicitly:
{% cv_context_button "edit_detail" some_object %}
!!! note "Hidden when there is no access"
cv_context_button renders nothing when the user lacks access to the target or the
action is disabled. This differs from the default {% cv_context_actions %} container,
which renders inaccessible buttons as disabled/greyed. Reach for the manual tag when
you want the button to disappear entirely.
Gate surrounding markup by permission
Use the cv_context_has_permission filter to render wrappers, headings, or separators only
when the user may access a key:
{% load crud_views %}
{% if view|cv_context_has_permission:"edit_detail" %}
<h3>Edit</h3>
{% cv_context_button "edit_detail" %}
{% endif %}
The filter checks access for view's current object (or None for list-type views) and
returns False for unknown keys.
Render a custom loop of buttons
view.cv_get_context_buttons returns the resolved, access-filtered button contexts (so
your loop never emits empty wrappers). Render each with cv_render_context_button:
{% load crud_views %}
{% for ctx in view.cv_get_context_buttons %}
<span class="my-wrap">{% cv_render_context_button ctx %}</span>
{% endfor %}
By default it iterates the view's cv_context_actions. Pass an explicit key list from your
own view method to control which buttons appear and in what order:
class AuthorDetailView(DetailViewPermissionRequired):
cv_viewset = cv_author
cv_context_actions = ["edit_detail", "delete"]
def get_toolbar_buttons(self):
return self.cv_get_context_buttons(keys=["edit_detail", "delete"])
## How do I link from one child collection to a sibling collection?
When you have a parent with several children (e.g. `Author` → `Book`, `Article`) and want a
button on one child's pages that jumps to a sibling collection under the *same* parent, use
[`SiblingContextButton`](reference/context_buttons.md#siblingcontextbutton). Place it on the
child viewset; it reuses the parent PK from the current URL:
```python
from crud_views.lib.viewset import ViewSet, ParentViewSet, context_buttons_default
from crud_views.lib.view import SiblingContextButton
cv_book = ViewSet(
model=Book,
name="book",
parent=ParentViewSet(name="author"),
context_buttons=context_buttons_default() + [
SiblingContextButton(key="articles", sibling_name="article", label_template_code="Articles"),
],
)
class BookListView(ListViewPermissionRequired):
cv_viewset = cv_book
cv_context_actions = ["parent", "create", "articles"]
Use ChildContextButton on the parent view to go down to a child, and
SiblingContextButton on a child view to go sideways to a sibling.
```