View Classes#

ViewSets#

class ModelViewSet(model: type[wildewidgets.models.ViewSetMixin] | None = None, url_prefix: str | None = None, url_namespace: str | None = None, **kwargs)[source]#

Bases: object

A viewset that provides CRUD operations for a Django model.

This class simplifies the creation of a complete set of views for a model, automatically generating URLs and configuring views for listing, creating, updating, and deleting model instances. It follows the Django REST Framework ViewSet pattern but for traditional Django views.

The viewset handles:

  • Index/list view with a data table

  • AJAX endpoint for table data loading

  • Bulk action processing (e.g., bulk delete)

  • Create view with a form

  • Update view with a form

  • Delete view

To use this class, create a subclass and set at minimum the model attribute:

Example

from wildewidgets import (
    BreadcrumbBlock,
    TablerVerticalNavbar,
    Menu,
    MenuItem,
)
from wildewidgets.viewsets import ModelViewSet
from myapp.models import Book

class MainMenu(Menu):
    items = [
        MenuItem(
            text="Home",
            icon="house",
            url=reverse_lazy("core:home"),
        ),
        MenuItem(
            text="Books",
            icon="mailbox",
            url=reverse_lazy("core:books--index"),
        ),
    ]

class MyNavbar(TablerVerticalNavbar):
    hide_below_viewport: str = "xl"
    branding = Block(
        LinkedImage(
            image_src=static("images/logo.png"),
            image_width="150px",
            image_alt="MyOrg",
            css_class="d-flex justify-content-center ms-3",
            url="https://www.example.com/",
        ),
    )
    contents = [
        MainMenu(),
    ]


class MyBreadcrumbs(BreadcrumbBlock):
    def __init__(self):
        super().__init__()
        self.add_breadcrumb(title="Home", url="/")

class BookViewSet(ModelViewSet):
    model = Book
    url_prefix = "books"
    url_namespace = "myapp"
    breadcrumbs_class = MyBreadcrumbs

# In urls.py
urlpatterns += BookViewSet().get_urlpatterns()
Keyword Arguments:
  • model – The model class to use (must be a wildewidgets.ViewSetMixin subclass)

  • url_prefix – Optional prefix for all URLs (defaults to model name)

  • url_namespace – Optional namespace for URL names

  • **kwargs – Additional attributes to set on the viewset

Raises:

ImproperlyConfigured – If model is not provided or not a ViewSetMixin subclass, or if model is missing required attributes

create_view_class#

The view class to use for the index view; must be a subclass of wildewidgets.views.generic.CreateView.

alias of CreateView

delete_view_class#

The view class to use for the index view; must be a subclass of wildewidgets.views.generic.DeleteView.

alias of DeleteView

index_table_class#

The wildewidgets.widgets.tables.base.BaseDataTable subclass to use for the listing table

alias of LookupModelTable

index_view_class#

The view class to use for the index view; must be a subclass of wildewidgets.views.generic.IndexView.

alias of IndexView

table_ajax_view_class#

The view class to use as the AJAX JSON endpoint for the dataTable; must be a subclass of wildewidgets.views.generic.TableAJAXView.

alias of TableAJAXView

table_bulk_action_view_class#

The view class to use for the index view; must be a subclass of wildewidgets.views.generic.CreateView.

alias of TableBulkActionView

update_view_class#

The view class to use for the index view; must be a subclass of wildewidgets.views.generic.UpdateView.

alias of UpdateView

get_breadcrumbs(view_name: str) wildewidgets.widgets.navigation.BreadcrumbBlock | None[source]#

Create breadcrumb navigation for the specified view.

This method returns a configured breadcrumb block for the current view. For views other than “index”, it adds a breadcrumb link back to the index view.

Parameters:

view_name – The name of the view (“index”, “create”, “update”, etc.)

Returns:

Configured breadcrumb block, or None if breadcrumbs_class is not set

get_index_table_kwargs() dict[str, Any][source]#

Get keyword arguments for configuring the index table.

This method creates a dictionary of configuration options for the data table on the index page. It automatically sets: - Default form actions if none are specified - The AJAX URL for fetching data - The form URL for bulk actions

Returns:

Configuration options for the data table

Return type:

dict[str, Any]

get_url_name(view_name: str, namespace: bool = True) str[source]#

Generate a URL name for a specific view.

This method creates a URL name by combining the model name with the view name. If namespace is True and a URL namespace is set, the namespace is prepended.

Parameters:
  • view_name – The base name of the view (e.g., “index”, “create”)

  • namespace – Whether to include the namespace prefix if available

Returns:

The complete URL name for the view

Return type:

str

Example

>>> viewset.get_url_name("create")
'myapp:book--create'  # (if namespace is 'myapp' and model name is 'book')
get_urlpatterns()[source]#

Generate URL patterns for all views.

This method creates a list of URL patterns for all CRUD operations: - Index/list view - AJAX endpoint for table data - Bulk action processing - Create view - Update view - Delete view

The URLs follow a consistent pattern based on the model name and any prefix.

Returns:

Django URL patterns for all views

Return type:

list

Example

>>> urlpatterns = BookViewSet().get_urlpatterns()
>>> # URLs will include patterns like 'books/', 'books/create/', etc.
breadcrumbs_class: type[BreadcrumbBlock] | None = None#

Set this to your wildewidgets.widgets.navigation.BreadcrumbBlock class to manage breadcrumbs automatically.

property create_view#

Get the configured create view.

This property returns a Django view function for creating new model instances, with form handling and success/error redirects.

Returns:

Configured create view

Return type:

View callable

property delete_view#

Get the configured delete view.

This property returns a Django view function for deleting model instances, with success redirect after deletion.

Returns:

Configured delete view

Return type:

View callable

index_table_kwargs: dict[str, Any] = {'buttons': True, 'page_length': 50, 'striped': True}#

A dictionary that we will use as the **kwargs for the constructor of table_class

property index_view#

Get the configured index view.

This property returns a Django view function for listing model instances in a data table, with all necessary configuration.

Returns:

Configured index view

Return type:

View callable

model: type[ViewSetMixin] | None = None#

The model we’re describing in this view. It must have wildewidgets.models.ViewSetMixin in its class heirarchy

navbar_class: type[Navbar] | None = None#

The navbar to use. We’ll highlight our verbose name in any of the menus within the navbar

property table_ajax_view#

Get the configured AJAX data endpoint view.

This property returns a Django view function that serves as the AJAX endpoint for the data table, providing data in JSON format.

Returns:

Configured AJAX view

Return type:

View callable

property table_bulk_action_view#

Get the configured bulk action view.

This property returns a Django view function for processing bulk actions on multiple model instances, such as bulk deletion.

Returns:

Configured bulk action view

Return type:

View callable

template_name: str | None = None#

The template name to use for all views

property update_view#

Get the configured update view.

This property returns a Django view function for updating existing model instances, with form handling and success/error redirects.

Returns:

Configured update view

Return type:

View callable

url_namespace: str | None = None#

The URL namespace to use for our view names. This should be set to the app_name set in the urls.py where this viewset’s patterns will be added to urlpatterns

url_prefix: str | None = None#

The path prefix to use to organize our views.

View Mixins#

class GenericViewMixin(*args, **kwargs)[source]#

Bases: object

Mixin providing common functionality for views that work with models.

This mixin adds methods and properties that simplify working with models in views, including logging utilities, permission handling, and UI helpers like breadcrumbs. It’s designed to be used with Django class-based views and is a core component of the generic views system.

Example

from django.views.generic import TemplateView
from wildewidgets.views.generic import GenericViewMixin

from myapp.models import MyModel

class MyView(GenericViewMixin, TemplateView):
    model = MyModel
    required_model_permissions = ['view']

    def get_content(self):
        # Use self.model_verbose_name, self.logging_extra, etc.
get_breadcrumbs() wildewidgets.widgets.navigation.BreadcrumbBlock | None[source]#

Get the breadcrumbs for this view, adding the current page title.

Returns:

The updated breadcrumb block or None

Return type:

BreadcrumbBlock | None

get_client_ip() str[source]#

Get the IP address of the client making the request.

This method checks for X-Forwarded-For headers first (for clients behind proxies) and falls back to REMOTE_ADDR if needed.

Returns:

The client’s IP address

Return type:

str

get_menu_item() str | None[source]#

Get the name of the main menu item that should be set as active.

Returns:

The plural verbose name of the model

Return type:

str | None

get_permissions_required() list[str][source]#

Get the list of permissions required to access this view.

This method combines permissions from the parent class with model-specific permissions based on the required_model_permissions attribute.

Returns:

List of permission strings

Return type:

list[str]

breadcrumbs: wildewidgets.widgets.navigation.BreadcrumbBlock | None = None#

Set this to your wildewidgets.widgets.navigation.BreadcrumbBlock to manage breadcrumbs automatically.

logger: Any = <Logger wildewidgets.views.generic (WARNING)>#

Set this to the logger of your choice

property logging_extra: str#

Get extra contextual information for log messages.

This property builds a string containing:

  • The client’s IP address

  • The current user’s username

  • The primary key of the current object (if applicable)

Returns:

A space-separated string of key=value pairs

Return type:

str

property model_logger_name: str#

Get a suitable name for logging messages about this model.

Returns:

The model name in lowercase, suitable for logging

Return type:

str

property model_name: str#

Get the name of the model class.

Returns:

The model class name

Return type:

str

property model_verbose_name: str#

Get the verbose name of the model, properly capitalized.

Returns:

The model’s verbose name

Return type:

str

property model_verbose_name_plural: str#

Get the plural verbose name of the model, properly capitalized.

Returns:

The model’s plural verbose name

Return type:

str

required_model_permissions: list[str] = []#

Set this to the model permissions the user must have in order to be authorized for this view:

class GenericDatatableMixin[source]#

Bases: object

Mixin providing datatable functionality for views that display model tables.

This mixin provides methods for configuring and instantiating DataTable widgets with appropriate settings and row actions. It handles common tasks like setting up action buttons based on user permissions and configuring table options.

Example

from django.views.generic import TemplateView
from wildewidgets import GenericDatatableMixin

from myapp.models import MyModel
from myapp.wildewidgets import MyCustomTable

class MyListView(GenericDatatableMixin, TemplateView):
    model = MyModel
    table_class = MyCustomTable

    def get_content(self):
        return self.get_table()
table_class#

The wildewidgets.widgets.tables.base.BaseDataTable subclass to use for the listing table

alias of LookupModelTable

get_table(*args, **kwargs) BaseDataTable[source]#

Create and configure a datatable instance.

This method instantiates the table_class with appropriate options and row action buttons based on user permissions.

Parameters:

*args – Positional arguments passed to the table constructor

Keyword Arguments:

**kwargs – Keyword arguments passed to the table constructor

Returns:

The configured datatable instance

Return type:

BaseDataTable

get_table_kwargs() dict[str, Any][source]#

Get keyword arguments for table initialization.

This method builds a dictionary of options to pass to the table constructor. If bulk actions are enabled but no specific actions are defined, it adds a default “delete” action.

Returns:

Keyword arguments for the table constructor

Return type:

dict[str, Any]

model: type[wildewidgets.models.ViewSetMixin] | None#
table_kwargs: dict[str, Any] = {'buttons': True, 'page_length': 25, 'striped': True}#

A dictionary that we will use as the **kwargs for the constructor of table_class

class WidgetInitKwargsMixin(*args, **kwargs)[source]#

Bases: object

Mixin that preserves widget initialization arguments for AJAX requests.

This mixin stores widget initialization arguments and provides methods to encode them for transmission in URLs and decode them from HTTP requests. This allows widgets to preserve their state between initial rendering and subsequent AJAX calls.

The mixin stores both positional and keyword arguments and can serialize them to base64-encoded JSON for inclusion in URLs or form data. The way it does it is as follows:

  • We make a dictionary

  • The positional arguments are stored in the “args” key.

  • The keyword arguments are stored in the “kwargs” key.

  • The resulting dictionary is then serialized to JSON and encoded as base64 for transmission.

  • The get_encoded_extra_data method returns the base64-encoded JSON string that can be included in URLs or form data.

  • The get_decoded_extra_data(request) method decodes the base64 string from the request and returns the original arguments as a dictionary.

The encoded data can be used in AJAX requests as the extra_data query parameter to reconstruct the widget’s state without needing to pass all arguments explicitly in the request.

This is primarily used by wildewidgets.WildewidgetDispatch to pass widget initialization arguments to tables and other widgets that require them for rendering or processing AJAX requests.

Examples

from wildewidgets import WidgetInitKwargsMixin, Widget

class MyWidget(WidgetInitKwargsMixin, Widget):
    def __init__(self, user_id, show_details=False, **kwargs):
        super().__init__(user_id, show_details=show_details, **kwargs)
        # The args and kwargs are now stored in self.extra_data
convert_extra(extra_item, first=True)[source]#

Convert extra data to URL query string format.

This method formats a dictionary as URL query parameters, either starting with “?” (if first=True) or “&” (if first=False).

Parameters:
  • extra_item – Dictionary of parameters to convert

  • first – Whether this is the first set of parameters in a URL

Returns:

Formatted URL query string segment

Return type:

str

get_decoded_extra_data(request)[source]#

Decode widget initialization arguments from an HTTP request.

This method extracts the “extra_data” parameter from the request’s GET parameters, decodes it from base64, and parses it as JSON.

Parameters:

request – The HTTP request containing encoded widget arguments

Returns:

Decoded initialization arguments (empty dict if none found)

Return type:

dict

get_encoded_extra_data()[source]#

Encode widget initialization arguments as base64 for URL transmission.

This method serializes the stored arguments to JSON, encodes them as base64, and returns them as a string that can be included in URLs.

Returns:

Base64-encoded JSON string of the initialization arguments

Return type:

str

class JSONResponseMixin[source]#

Bases: object

Mixin that provides JSON response handling for views.

This mixin allows views to return JSON responses by converting the context data from get_context_data() into a JSON string and returning it with the appropriate content type. It also handles adding standard result indicators and removing non-serializable view objects.

Attributes: .. rubric:: Examples

from django.utils import timezone
from django.views import View
from wildewidgets import JSONResponseMixin

def get_some_data():
    return {"key": "value", "another_key": 42}

class MyJSONView(JSONResponseMixin, View):
    def get_context_data(self, **kwargs):
        return {
            'data': get_some_data(),
            'timestamp': timezone.now().isoformat()
        }
get(request: HttpRequest, *args, **kwargs) HttpResponse[source]#

Handle GET requests by returning a JSON response.

This method:

  1. Processes the request to extract the CSRF token

  2. Gets context data from get_context_data()

  3. Adds a “result” field if not in clean mode

  4. Removes non-serializable view object

  5. Serializes to JSON and returns the response

Parameters:
  • request – The HTTP request

  • *args – Additional positional arguments

  • **kwargs – Additional keyword arguments

Returns:

HTTP response with JSON content

Return type:

HttpResponse

Raises:

AssertionError – If get_context_data() doesn’t return a dictionary

get_json_response(content: Any, **httpresponse_kwargs) HttpResponse[source]#

Create a properly configured HttpResponse with JSON content type.

This method creates an HttpResponse with the provided content and sets the content type to “application/json”. It also adds cache control headers to prevent caching of the response.

Parameters:
  • content – The content to include in the response

  • **httpresponse_kwargs – Additional keyword arguments for HttpResponse

Returns:

Configured HTTP response with JSON content

Return type:

HttpResponse

post(*args, **kwargs) HttpResponse[source]#

Handle POST requests by delegating to the GET handler.

This allows the same JSON response logic to be used for both GET and POST requests.

Parameters:
  • *args – Positional arguments to pass to get()

  • **kwargs – Keyword arguments to pass to get()

Returns:

JSON response from get() method

Return type:

HttpResponse

render_to_response(data: str) HttpResponse[source]#

Return a JSON response containing the provided data.

Parameters:

data – JSON string to include in the response

Returns:

HTTP response with JSON content type

Return type:

HttpResponse

is_clean: bool = False#

If True, return context data as-is without adding a “result” field. If False, add “result”: “ok” or “result”: “error” based on the presence of error indicators.

class StandardWidgetMixin[source]#

Bases: object

A mixin for views that use a standard widget-based template structure.

This mixin provides a convention for template-less views that render their content using widgets. It automatically adds the content widget and optional breadcrumbs widget to the template context.

To use this mixin: 1. Override get_content to return the main content widget 2. Optionally override get_breadcrumbs to provide breadcrumb navigation 3. Ensure your template includes the necessary blocks and loads the

wildewidgets template tags

The template used by your derived class should include at least the following:

{% extends "<your_base_template>.html" %}
{% load  wildewidgets %}

{% block title %}{{page_title}}{% endblock %}

{% block breadcrumb-items %}
{% if breadcrumbs %}
    {% wildewidgets breadcrumbs %}
{% endif %}
{% endblock %}

{% block content %}
{% wildewidgets content %}
{% endblock %}

Examples

Basic view using the StandardWidgetMixin:

from django.views.generic import TemplateView
from wildewidgets.views.mixins import StandardWidgetMixin
from wildewidgets import Block, BreadcrumbBlock

class HomeContentWidget(Block):
    block = "home-content"
    tag = "h1"

    def __init__(self, user):
        super().__init__(f"Welcome, {user.username}!")


class AppBreadcrumbs(BreadcrumbBlock):
    def __init__(self):
        super().__init__()
        self.add_breadcrumb('Home', url='/')


class HomeView(StandardWidgetMixin, TemplateView):
    template_name = 'myapp/standard.html'

    def get_content(self):
        return HomeContentWidget(user=self.request.user)

    def get_breadcrumbs(self):
        breadcrumbs = AppBreadcrumbs()
        breadcrumbs.add_breadcrumb('Home')
        return breadcrumbs
get_breadcrumbs() BreadcrumbBlock | None[source]#

Get the breadcrumbs widget for the page.

Override this method to provide breadcrumb navigation. By default, no breadcrumbs are shown.

Returns:

Breadcrumb widget or None if no breadcrumbs

Return type:

BreadcrumbBlock | None

get_content()[source]#

Get the main content widget for the page.

This method must be overridden by subclasses to provide the widget that will be rendered in the content block.

Returns:

The main content widget

Return type:

Widget

Raises:

NotImplementedError – If not overridden by subclass

get_context_data(**kwargs: Any) dict[str, Any][source]#

Add content widget and breadcrumbs to the template context.

This method: 1. Gets content widget from get_content() 2. Gets optional breadcrumbs widget from get_breadcrumbs() 3. If breadcrumbs exist, adds them and sets page_title 4. Delegates to parent class for additional context

Parameters:

**kwargs – Additional context variables

Returns:

The updated template context

Return type:

dict

class PermissionRequiredMixin[source]#

Bases: AccessMixin

A class-based view mixin that controls access based on user permissions and group membership.

This mixin provides a flexible permission system that can authorize users based on:

  • Django group membership

  • Django permissions

  • Model-specific permissions

Authorization Rules:

  • Django superusers are always authorized

  • Anonymous users are never authorized

  • Users in any of the groups specified by groups_required are authorized

  • Users with any of the permissions specified by permissions_required are authorized

  • When model and required_model_permissions are set, the mixin automatically checks the corresponding model permissions (e.g., “app.add_model”, “app.change_model”)

The mixin also provides helper methods to check specific permissions for common operations like viewing, creating, updating, and deleting.

Example

from django.contrib.auth.models import User
from django.views.generic import TemplateView
from wildewidgets import PermissionRequiredMixin

class StaffRequiredView(PermissionRequiredMixin, TemplateView):
    template_name = "staff_only.html"
    groups_required = ["Staff"]

class UserModelView(PermissionRequiredMixin, TemplateView):
    template_name = "user_management.html"
    model = User
    required_model_permissions = ["view", "change"]
check_permissions(groups_required: list[django.contrib.auth.models.Group] | None = None, permissions_required: list[str] | None = None) bool[source]#

Check if the current user is authorized based on groups and permissions.

This is the core authorization method that implements the following logic: 1. Superusers are always authorized 2. If the user belongs to any required group, they are authorized 3. If the user has any of the required permissions, they are authorized 4. Otherwise, authorization is denied

If model permissions are configured via model and required_model_permissions, they are automatically added to the permissions check.

Keyword Arguments:
Returns:

True if the user is authorized, False otherwise

Return type:

bool

dispatch(request: HttpRequest, *args: Any, **kwargs: Any) Any[source]#

Process the request and enforce permission checks.

This method intercepts all requests to the view and checks if the user has the required permissions before allowing the request to proceed.

Parameters:
  • request – The HTTP request

  • *args – Positional arguments to pass to the handler

Keyword Arguments:kk

**kwargs: Keyword arguments to pass to the handler

Returns:

The response from the view

Return type:

Any

Raises:

PermissionDenied – If the user doesn’t have the required permissions

get_groups_required() list[django.contrib.auth.models.Group][source]#

Get the list of Django Group objects required for authorization.

This method converts the group names in groups_required to actual Group objects.

Returns:

List of Django Group objects that grant access

Return type:

list[Group]

get_model_permissions(model: Model | type[Model] | None, perms: list[str]) list[str][source]#

Convert simple permission names to fully-qualified model permission strings.

This method transforms basic permission types like “view”, “add”, “change”, “delete” into fully-qualified permission strings like “app_label.view_modelname”.

Parameters:
  • model – The model class (ignored - uses self.model instead)

  • perms – List of basic permission types to convert

Returns:

List of fully-qualified permission strings

Return type:

list[str]

Raises:

ImproperlyConfigured – If model is not set to a valid Django model class

Example

>>> # If self.model is User from django.contrib.auth
>>> self.get_model_permissions(None, ["add", "change"])
['auth.add_user', 'auth.change_user']
get_permissions_required() list[str][source]#

Get the list of permission strings required for authorization.

Returns:

List of permission strings that grant access

Return type:

list[str]

user_can_create() bool[source]#

Check if the current user has permission to create instances of the model.

This is a convenience method that checks for the “add” model permission.

Returns:

True if the user has create permission, False otherwise

Return type:

bool

Raises:

ImproperlyConfigured – If model is not set

user_can_delete() bool[source]#

Check if the current user has permission to delete instances of the model.

This is a convenience method that checks for the “delete” model permission.

Returns:

True if the user has delete permission, False otherwise

Return type:

bool

Raises:

ImproperlyConfigured – If model is not set

user_can_update() bool[source]#

Check if the current user has permission to update instances of the model.

This is a convenience method that checks for the “change” model permission.

Returns:

True if the user has update permission, False otherwise

Return type:

bool

Raises:

ImproperlyConfigured – If model is not set

user_can_view() bool[source]#

Check if the current user has permission to view the model.

This is a convenience method that checks for the “view” model permission.

Returns:

True if the user has view permission, False otherwise

Return type:

bool

Raises:

ImproperlyConfigured – If model is not set

groups_required: list[str] | None = None#

Users who are members of the named Django auth groups will be permitted access to the view, and those who are not will be denied access.

model: type[Model] | None#

Used in conjunction with required_model_permissions, this is the model we want to act on. This should be set by our our subclass, which is why it is just a type declaration here. This is used by get_model_permissions

permissions_required: list[str] | None = None#

Users who have any of the listed Django model permissions will be permitted access to the view.

required_model_permissions: list[str] | None = None#

A list of simple strings like view, add, change, delete that represent actions that can be done on a model. This is used by py:meth:get_model_permissions

AJAX Views#

class JSONResponseView(**kwargs)[source]#

Bases: JSONResponseMixin, TemplateView

A view that renders a template and returns the result as a JSON response.

This view combines Django’s TemplateView with JSONResponseMixin to provide a simple way to return template-rendered content within a JSON response. This is useful for AJAX requests that need to return HTML fragments within a JSON structure.

When subclassing, you typically need to override the template_name attribute and optionally the get_context_data method.

template_name#

The template to render (must be set by subclasses)

Example

class MyJSONView(JSONResponseView):
    template_name = "my_template.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['extra_data'] = get_some_data()
        return context
class JSONDataView(**kwargs)[source]#

Bases: View

A view that returns JSON data in response to HTTP requests.

This class provides a simple framework for views that need to return JSON data. It handles the HTTP request/response cycle and serializes the context data to JSON. By default, it only responds to GET requests.

To use this class, subclass it and override the get_context_data method to provide the data you want to return as JSON.

Example

class UserDataView(JSONDataView):
    def get_context_data(self, **kwargs):
        user_id = self.kwargs.get('user_id')
        user = User.objects.get(id=user_id)
        return {
            'username': user.username,
            'email': user.email,
            'date_joined': user.date_joined.isoformat()
        }
get(request: HttpRequest, *args, **kwargs) JsonResponse[source]#

Handle GET requests by returning JSON data.

This method retrieves the context data and returns it as a JSON response.

Parameters:
  • request – The HTTP request object

  • *args – Additional positional arguments

  • **kwargs – Additional keyword arguments

Returns:

HTTP response containing the JSON-serialized context data

Return type:

JsonResponse

get_context_data(**kwargs) dict[str, Any][source]#

Get the data to include in the JSON response.

Override this method to provide the data you want to include in the response. By default, it returns an empty dictionary.

Parameters:

**kwargs – Additional context data

Returns:

The data to serialize to JSON

Return type:

dict

render_to_response(context, **response_kwargs) JsonResponse[source]#

Create a JSON response from the context data.

This method serializes the context data to JSON and returns it as an HTTP response.

Parameters:
  • context – The data to serialize to JSON

  • **response_kwargs – Additional response parameters (unused)

Returns:

HTTP response containing the JSON-serialized context data

Return type:

JsonResponse

class WildewidgetDispatch(*args, **kwargs)[source]#

Bases: WidgetInitKwargsMixin, View

A view that dynamically dispatches requests to widget classes.

This view acts as a central dispatcher for widget AJAX requests. It examines the request parameters to determine which widget class to instantiate, then delegates the request handling to that widget’s dispatch method.

The view searches for widget classes in all installed Django apps by looking for a ‘wildewidgets.py’ file or a ‘wildewidgets’ directory within each app.

This approach allows widgets to handle their own AJAX requests without requiring explicit URL routing for each widget type.

Example usage in URLs:
path(
    'wildewidget/',
    WildewidgetDispatch.as_view(),
    name='wildewidget_dispatch'
)
Example client-side code:
$.ajax({
    url: '/wildewidget/',
    data: {
        'wildewidgetclass': 'MyWidget',
        'extra_data': encodeURIComponent(JSON.stringify({
            args: [],
            kwargs: {param1: 'value1'}
        }))
    }
});
dispatch(request: HttpRequest, *args, **kwargs) django.http.response.HttpResponseBase | django.http.response.Http404[source]#

Dispatch the request to the appropriate widget class.

This method:

  1. Extracts the widget class name from the request

  2. Searches for the widget class in all installed apps

  3. Instantiates the widget class with the provided arguments

  4. Delegates to the widget’s dispatch method

Parameters:
  • request – The HTTP request object

  • *args – Additional positional arguments

Keyword Arguments:

**kwargs – Additional keyword arguments

Returns:

The response from the widget’s dispatch method Http404: If the widget class cannot be found

Return type:

HttpResponseBase

Note

The request must include: - ‘wildewidgetclass’: The name of the widget class to instantiate

The request may include: - ‘csrf_token’: Optional CSRF token for protected requests - ‘extra_data’: Optional base64 encoded JSON encoded string

containing a dict with ‘args’ and ‘kwargs’ keys for widget initialization

Generic Views#

class IndexView(*args, **kwargs)[source]#

Bases: LoginRequiredMixin, PermissionRequiredMixin, GenericViewMixin, GenericDatatableMixin, NavbarMixin, StandardWidgetMixin, TemplateView

Generic view for displaying a list of model instances in a table.

This view provides a complete implementation for displaying model data in a table with support for sorting, filtering, pagination, and row actions. It requires minimal configuration - typically just setting the model attribute.

The view automatically handles:

  • User authentication and permission checking

  • Table configuration and rendering

  • Create button based on user permissions

model#

The model class to display

Type:

type[ViewSetMixin] | None

required_model_permissions#

List of permissions required to access this view

Type:

list[str]

Example

from django.db import models
from wildewidgets import IndexView

class Book(models.Model, ViewSetMixin):
    title = models.CharField(max_length=255)
    author = models.CharField(max_length=255)
    published_date = models.DateField()

    class Meta:
        verbose_name = "book"
        verbose_name_plural = "books"

class BookListView(IndexView):
    model = Book
    # That's it! The view is ready to use.
get_content() Widget[source]#

Get the main content for this view.

Returns:

An IndexTableWidget configured for the model

Return type:

Widget

Raises:

ImproperlyConfigured – If model is not set

get_title() str[source]#

Get the page title for this view.

Returns:

The plural verbose name of the model

Return type:

str

model: type[ViewSetMixin] | None = None#

The model we’re describing in this view. It must have wildewidgets.models.ViewSetMixin in its class heirarchy

required_model_permissions: list[str] = ['view', 'add', 'change', 'delete']#

A list of simple strings like view, add, change, delete that represent actions that can be done on a model. This is used by py:meth:get_model_permissions

class TableAJAXView(*args, **kwargs)[source]#

Bases: LoginRequiredMixin, PermissionRequiredMixin, WidgetInitKwargsMixin, GenericDatatableMixin, View

View that handles AJAX requests for datatable data.

This view processes AJAX requests from the client-side DataTables library, returning filtered, sorted, and paginated data as JSON. It handles all the server-side processing required by DataTables.

This view is typically used on its own, without a template, to provide data source for the model.

By default we use wildewidgets.LookupModelTable as the table_class, but you can override this to use any wildewidgets.widgets.tables.base.BaseDataTable subclass.

Example

from wildewidgets.views.generic import TableAJAXView

from myapp.models import MyModel

class MyModelTableAJAXView(TableAJAXView):
    model = MyModel
dispatch(request: HttpRequest, *args, **kwargs) HttpResponseBase[source]#

Process incoming requests and delegate to the table’s dispatch method.

This method extracts CSRF token and initialization parameters from the request, sets them on the table instance, and then delegates to the table’s own dispatch method for handling the AJAX request.

Parameters:
  • request – The HTTP request

  • *args – Additional positional arguments

Kwargs:

**kwargs: Additional keyword arguments

Returns:

The JSON response from the table

Return type:

HttpResponse

model: type[ViewSetMixin] | None = None#

The model we’re describing in this view. It must have wildewidgets.models.ViewSetMixin in its class heirarchy

required_model_permissions: list[str] = ['view', 'add', 'change', 'delete']#

A list of simple strings like view, add, change, delete that represent actions that can be done on a model. This is used by py:meth:get_model_permissions

class TableBulkActionView(*args, **kwargs)[source]#

Bases: LoginRequiredMixin, PermissionRequiredMixin, GenericViewMixin, GenericDatatableMixin, MessageMixin, TableActionFormView

View that handles bulk actions on multiple table rows.

This view processes form submissions for bulk actions on datatable rows, such as deleting multiple items at once. It provides a default implementation for bulk deletion and can be extended for other bulk actions.

Example

from wildewidgets import TableBulkActionView

class BookBulkActionView(TableBulkActionView):
    model = Book

    def process_archive_action(self, items):
        # Custom bulk action implementation
        Book.objects.filter(id__in=items).update(archived=True)
process_delete_action(items: list[str]) None[source]#

Process a bulk delete action.

This method deletes all model instances with IDs in the provided list, logs the action, and displays a success message.

Parameters:

items – List of primary key strings for the items to delete

logger: Any = <Logger wildewidgets.views.generic (WARNING)>#

Set this to the logger of your choice

model: type[ViewSetMixin] | None = None#

The model we’re describing in this view. It must have wildewidgets.models.ViewSetMixin in its class heirarchy

required_model_permissions: list[str] = ['delete']#

A list of simple strings like view, add, change, delete that represent actions that can be done on a model. This is used by py:meth:get_model_permissions

class CreateView(*args, **kwargs)[source]#

Bases: LoginRequiredMixin, PermissionRequiredMixin, FormInvalidMessageMixin, FormValidMessageMixin, GenericViewMixin, NavbarMixin, StandardWidgetMixin, CreateView

Generic view for creating new model instances.

This view provides a complete implementation for creating new model instances with form validation, permission checking, and success/error messaging. It uses the wildewidgets.FormPageLayout by default to render the form in an attractive layout.

Example

from django.db import models
from wildewidgets import CreateView, ViewSetMixin

class Book(models.Model, ViewSetMixin):
    title = models.CharField(max_length=255)
    author = models.CharField(max_length=255)
    published_date = models.DateField()

    class Meta:
        verbose_name = "book"
        verbose_name_plural = "books"

class BookCreateView(CreateView):
    model = Book
    fields = ['title', 'author', 'published_date']
layout_widget#

Use this AbstractFormPageLayout subclass to render our page

alias of FormPageLayout

get_content() Widget[source]#

Get the main content for this view.

Returns:

A form layout widget with the create form

Return type:

Widget

get_form_class() type[Form | ModelForm] | None[source]#

Get the form class to use for creating the model instance.

If the model has a get_create_form_class method, use that form class. Otherwise, fall back to the default behavior.

Returns:

The form class to use

Return type:

type

get_form_invalid_message()[source]#

Get the message to display when form validation fails.

This method also logs the validation failure.

Returns:

The error message

Return type:

str

get_form_valid_message()[source]#

Get the message to display when a new instance is successfully created.

This method also logs the successful creation.

Returns:

The success message

Return type:

str

get_title() str[source]#

Get the page title for this view.

Returns:

A title indicating creation of a new instance

Return type:

str

required_model_permissions: list[str] = ['add']#

A list of simple strings like view, add, change, delete that represent actions that can be done on a model. This is used by py:meth:get_model_permissions

class UpdateView(*args, **kwargs)[source]#

Bases: LoginRequiredMixin, PermissionRequiredMixin, FormInvalidMessageMixin, FormValidMessageMixin, GenericViewMixin, NavbarMixin, StandardWidgetMixin, UpdateView

Generic view for updating existing model instances.

This view provides a complete implementation for updating model instances with form validation, permission checking, and success/error messaging. It uses the FormPageLayout by default to render the form in an attractive layout.

Example

from django.db import models
from wildewidgets import CreateView, ViewSetMixin

class Book(models.Model, ViewSetMixin):
    title = models.CharField(max_length=255)
    author = models.CharField(max_length=255)
    published_date = models.DateField()

    class Meta:
        verbose_name = "book"
        verbose_name_plural = "books"

class BookUpdateView(UpdateView):
    model = Book
    fields = ['title', 'author', 'published_date']
layout_widget#

Use this AbstractFormPageLayout subclass to render our page

alias of FormPageLayout

get_content() Widget[source]#

Get the main content for this view.

Returns:

A form layout widget with the update form

Return type:

Widget

get_form_class() type[BaseModelForm][source]#

Get the form class to use for updating the model instance.

If the object has a get_update_form_class method, use that form class. Otherwise, fall back to the default behavior.

Returns:

The form class to use

Return type:

type

get_form_invalid_message()[source]#

Get the message to display when form validation fails.

This method also logs the validation failure.

Returns:

The error message

Return type:

str

get_form_valid_message()[source]#

Get the message to display when an instance is successfully updated.

This method also logs the successful update.

Returns:

The success message

Return type:

str

get_title() str[source]#

Get the page title for this view.

Returns:

A title indicating update of the instance

Return type:

str

required_model_permissions: list[str] = ['change']#

A list of simple strings like view, add, change, delete that represent actions that can be done on a model. This is used by py:meth:get_model_permissions

class DeleteView(*args, **kwargs)[source]#

Bases: LoginRequiredMixin, PermissionRequiredMixin, GenericViewMixin, FormInvalidMessageMixin, FormValidMessageMixin, BaseDeleteView

Generic view for deleting model instances.

This view provides a complete implementation for deleting model instances with permission checking and success/error messaging. It only responds to POST requests for security reasons.

Example

from django.db import models
from wildewidgets import DeleteView, ViewSetMixin

class Book(models.Model, ViewSetMixin):
    title = models.CharField(max_length=255)
    author = models.CharField(max_length=255)
    published_date = models.DateField()

    class Meta:
        verbose_name = "book"
        verbose_name_plural = "books"


class BookDeleteView(DeleteView):
    model = Book
    success_url = reverse_lazy('book-list')
form_invalid(form: BaseModelForm) HttpResponse[source]#

Handle form validation failures by redirecting to the success URL.

Since DeleteView often doesn’t render a form, we redirect even on validation failures rather than re-rendering the form.

Parameters:

form – The form that failed validation (unused)

Returns:

Redirect to success_url

Return type:

HttpResponse

get_form_class() type[BaseModelForm][source]#

Get the form class to use for deleting the model instance.

If the object has a get_delete_form_class method, use that form class. Otherwise, fall back to the default behavior.

Returns:

The form class to use

Return type:

type

get_form_invalid_message()[source]#

Get the message to display when deletion fails.

This method also logs the failure.

Returns:

The error message

Return type:

str

get_form_valid_message()[source]#

Get the message to display when an instance is successfully deleted.

This method also logs the successful deletion.

Returns:

The success message

Return type:

str

http_method_names: list[str] = ['post']#

The HTTP methods this view responds to. We only allow POST for security.

model: type[ViewSetMixin] | None = None#

The model we’re describing in this view. It must have wildewidgets.models.ViewSetMixin in its class heirarchy

required_model_permissions: list[str] = ['delete']#

The required model permissions for this view.