django-cruditor

All Contents

Installation

django-cruditor supports Python 3 only and requires at least Django 1.11 (because of the template based widget rendering). Optional dependencies are django-tables2, django-filter and django-tapeforms. Depending on what parts of django-cruditor you want to use, you have to install them manually.

To start, simply install the latest stable package using the command

$ pip install django-cruditor

In addition, you have to add 'cruditor' to the INSTALLED_APPS setting in your settings.py.

If you’re planing to us the ListViews provided django-cruditor, you have to install django-tables2 and add need to add 'django_tables2' to your INSTALLED_APPS.

If you want to use the form rendering of the Add- or ChangeViews, you’ll need django-tapeforms. Don’t forget to add tapeforms to your settings’ INSTALLED_APPS.

Finally, if you want to use the filtering capabilities of django-cruditor ListViews, install django-filter and add django_filters to your INSTALLED_APPS.

Thats it, now continue to the Usage section to learn how to render your forms to HTML.

Usage

The best you can do right now is have a look on the examples. Every feature is demo’ed there.

  • Minimal code one has to write to create a view in the Cruditor context (examples/minimal)

  • How to provide a classic List/Add/Change/Delete set of views with nearly no effort (examples/collection)

  • How to provide filters in the list view to find the right objects (examples/collection)

  • How to work with data not coming form the Django ORM (examples/remote)

  • How to integrate inline formsets for related data (examples/formset)

To start, just check out the repository and run the examples project. After creating a superuser you can log in and find all demos in the menu.

API Reference

Mixins

class cruditor.mixins.CruditorMixin[source]

Bases: object

Base mixin for all Cruditor views. Provides common functionality for all views.

It is a good idea to have a own “base” mixin to configure the common options like menu_title, the urls and templates.

Usually you might have required_permission configured per-view.

menu_title = 'CRUDitor'[source]

Title to use in templates / menu bar

index_url = '#'[source]

URL to use in the linked menu_title

logout_url = '#'[source]

URL to use when providing a logout link to the user.

change_password_url = None[source]

URL to the change password view, if available.

menu_template_name = 'cruditor/includes/menu.html'[source]

Template name which is included to render the menu.

extrahead_template_name = 'cruditor/includes/extrahead.html'[source]

Template used to include extra head stuff.

login_template_name = 'cruditor/login.html'[source]

Page template for the login view.

login_form_class[source]

Form class which is used in the login view.

alias of LoginForm

staff_required = True[source]

Decide if only staff users should be able to use the Cruditor views.

required_permission = None[source]

Which permission is required to access the view.

model_verbose_name = None[source]

If not provided, Cruditor tries to look up the verbose name from model.Meta

dispatch(request, *args, **kwargs)[source]

Ensure the user is logged in (by calling ensure_logged_in` method). If the user is logged in, permissions are checked by calling ensure_required_permission.

get_cruditor_context(alternative_title=None, login_context=False)[source]

Provides some context for all Cruditor templates to render menu, header, breadcrumb and title buttons.

The method takes an optional argument alternative_title to override the default title from get_title method.

get_title()[source]

Returns the title of the page. Uses view’s title property. If not set falls back to menu_title.

get_breadcrumb_title()[source]

By default, the breadcrumb title is the same as the page title. Calls get_title if not overwritten.

get_breadcrumb()[source]

This method is expected to return a list of breadcrumb elements as a list.

Every breadcrumb element is a dict or object with at least a title property/key. If a url key/property is provided, the item is linked.

get_titlebuttons()[source]

This method is expected to return None or a list of buttons to display in the title row of the page.

Every button element is a dict or object with at least a label and url property/key. In addition, one can provide an alternative button_class which is used as a css class - pefixed with “btn-“. Default button_class is “light”.

get_model_verbose_name()[source]

Returns the verbose name of the handled object/item.

If model_verbose_name is set, the value is used. If not, Cruditor tries to get the verbose name from the model property (via Meta class). If no name is available at all, “Item” is returned.

ensure_logged_in(request, *args, **kwargs)[source]

This method checks if the request user is logged in and has the right flags set (e.g. is_staff if staff_required is set in view).

If user is logged in, True is returned. If not, handle_not_logged_in is called.

handle_not_logged_in(request, *args, **kwargs)[source]

This method is responsible to handle not logged-in users. By default, renders the Django login view using a Cruditor optimized template using the login_form_class as Form.

get_required_permission()[source]

Returns the required Django permissions required to access the view.

You might override the method to apply more complex rules on what permissions are required.

ensure_required_permission()[source]

This method ensures that all required permissions (fetched by calling get_required_permission).

If permissions are not met, PermissionDenied is raised.

get_context_data(**kwargs)[source]

Adds the cruditor context variable to the template context. Uses data from get_cruditor_context method.

class cruditor.mixins.FormViewMixin[source]

Bases: object

Mixin to add formset support to Django FormViews. To use formsets, you have to provide a set of formsets as a dict (or OrderedDict if you have more than one formset - just to have a defined ordering).

formset_classes = None[source]
get_formset_classes()[source]

This method returns the formset classes to render in the form view. By default, returns the formset_classes property.

get_formset_kwargs(formset_class)[source]

This method returns additional kwargs to initialize a formset. The formset_class is provided to ensure the method can return proper kwargs.

get(request, *args, **kwargs)[source]

Extended get-method to render to form and all formsets properly initialized.

post(request, *args, **kwargs)[source]

Extended version of the FormView.post method which validates the form and all configured formsets. If everything is valid, form_valid is called. If something is not valid, form_invalid is called.

Both the form instance and all formset instances are provided to the called method. The form is passed as the first argument, the formsets are passed as keyword arguments using the formset key from formset_classes.

save_form(form, **formsets)[source]

This method is called from form_valid to actual save the data from the form and all formsets. All saving is done by default.

get_success_message()[source]

Returns the success message to display when the form is valid.

form_valid(form, **formsets)[source]

Saves the data and provides a nice success message, then redirects to the get_success_url url.

form_invalid(form, **formsets)[source]

Re-render the page with the invalid form and/or formsets.

Forms

class cruditor.forms.CruditorTapeformMixin(*args, **kwargs)[source]

Bases: Bootstrap4TapeformMixin

Cruditor mixin for all forms (relies on django-tapeforms).

class cruditor.forms.CruditorFormsetMixin[source]

Bases: object

Helper mixin to provide some additional configuration to the javascript part of Cruditor’s formset support, mainly translations but also all other stuff which might be needed.

js_formset_options = None[source]
template_context[source]

This cached property can be used to access extra context in the formset template while keeping the performance up by not “generating” the context over and over again. The return value of this property is generated by calling the method get_template_context once per formset instance.

get_template_context()[source]

This method builds a context which is used by the template_context property to return additional context when rendering the formset. Some defaults are already set and might be overwritten.

add_fields(form, index)[source]

Overwritten method to make sure the DELETE marker field is hidden in output.

get_js_formset_options()[source]

This method builds the options dict for the javascript part. Some defaults are merged with js_formset_options property.

class cruditor.forms.CruditorFormsetFormMixin(*args, **kwargs)[source]

Bases: CruditorTapeformMixin

Helper mixin for forms in a formset, used together with Cruditor-enabled formsets.

visible_fields()[source]

This method is overwritten to make sure that the DELETE marker field is not considered when returning the list of visible fields.

hidden_fields()[source]

This method is overwritten to make sure that the DELETE marker field is not considered when returning the list of hidden fields. Cruditor template renders the field manually.

class cruditor.forms.LoginForm(*args, **kwargs)[source]

Bases: CruditorTapeformMixin, AuthenticationForm

Tapeform-enabled version of the Django AuthenticationForm.

base_fields = {'password': <django.forms.fields.CharField object>, 'username': <django.contrib.auth.forms.UsernameField object>}[source]
declared_fields = {'password': <django.forms.fields.CharField object>, 'username': <django.contrib.auth.forms.UsernameField object>}[source]
property media[source]

Return all media required to render the widgets on this form.

class cruditor.forms.ChangePasswordForm(*args, **kwargs)[source]

Bases: CruditorTapeformMixin, SetPasswordForm

Tapeform-enabled version of the Django SetPasswordForm.

base_fields = {'new_password1': <django.forms.fields.CharField object>, 'new_password2': <django.forms.fields.CharField object>}[source]
declared_fields = {'new_password1': <django.forms.fields.CharField object>, 'new_password2': <django.forms.fields.CharField object>}[source]
property media[source]

Return all media required to render the widgets on this form.

Filters

class cruditor.filters.AnyChoiceFilter(*args, **kwargs)[source]

Bases: ChoiceFilter

Extended ChoiceFilter which adds an “any” choice to the choices from the field / provided options by setting a empty_label on the generated form field.

class cruditor.filters.MultiCharFilter(fields, *args, **kwargs)[source]

Bases: CharFilter

This filter performs an OR query on the defined fields from a single entered value.

The following will work similar to the default UserAdmin search:

class UserFilterSet(FilterSet):
    search = MultiCharFilter([
        'username', 'first_name', 'last_name', '^email'])

    class Meta:
        model = User
        fields = ['search']

The filter supports filtering in different modes (icontains, istartswith, iexact, and search). icontains is the default mode, use ^, = and @ in the list of fields for the other modes.

Based on some ideas from https://gist.github.com/nkryptic/4727865

default_lookup_type = 'icontains'[source]
lookup_types = [('^', 'istartswith'), ('=', 'iexact'), ('@', 'search')][source]
filter(qs, value)[source]

Views

class cruditor.views.Cruditor404View(**kwargs)[source]

Bases: CruditorMixin, TemplateView

Customized not found page. Needed to add the required cruditor context for properly rendered templates.

template_name = 'cruditor/404.html'[source]

Template used to render the 404 page.

dispatch(request, *args, **kwargs)[source]

Ensure the user is logged in (by calling ensure_logged_in` method). If the user is logged in, permissions are checked by calling ensure_required_permission.

class cruditor.views.Cruditor403View(**kwargs)[source]

Bases: CruditorMixin, TemplateView

Customized permission denied page. Needed to add the required cruditor context for properly rendered templates.

template_name = 'cruditor/403.html'[source]

Template used to render the 403 page.

dispatch(request, *args, **kwargs)[source]

Ensure the user is logged in (by calling ensure_logged_in` method). If the user is logged in, permissions are checked by calling ensure_required_permission.

class cruditor.views.CruditorListView(**kwargs)[source]

Bases: CruditorMixin, TemplateView

Enhanced list view backed by django-tables2 and django-filters.

You want to set at least the model property. The remaining default property values are just fine for a working output.

By providing a alternative table_class and/or filter_class you can improve the usability of the view even further.

model = None[source]

Model to work on in this view.

queryset = None[source]

Queryset to use for looking up objects.

filter_class = None[source]

Optional django_filters.FilterSet class to provide filtering capabilities.

table_class = None[source]

Required django_tables2.Table class to change the rendered table.

template_name = 'cruditor/list.html'[source]

Template to use when rendering the list view.

get_context_data(**kwargs)[source]

Prepares the context by adding the table context variable. If you have configured filter_class, the filter_form context variable will be provided too.

get_queryset()[source]

Provide a queryset to fetch data with. If queryset is set on the class, the value will be used, if not but model is set, the default manager is used.

If both queryset and model is not set, you have to override this method to provide data to display.

get_table_class()[source]

Method to override the used table class. By default, returns table_class property if set.

If no table_class``is provided, an ``ImproperlyConfigured exception is raised.

get_table_kwargs()[source]

Override to provide additional kwargs when initializing the table object.

get_filter_class()[source]

Method to override the used filter class from django_filters. By default, returns filter_class property if set.

get_filter_kwargs()[source]

Override to provide additional kwargs when initializing the filterset object.

get_filtered_queryset()[source]

Filter the base queryset using the django-filters FilterSet if available. QuerySet is passed if no filter_class is defined.

get_table(filtered_qs)[source]

Prepare the table object using the provided QuerySet/Iterable.

class cruditor.views.CruditorAddView(**kwargs)[source]

Bases: CruditorMixin, FormViewMixin, CreateView

Enhanced view to add new items using a form view.

success_message = 'The {model} "{object}" was successfully added.'[source]

Message used when a new item was added successfully.

template_name = 'cruditor/form.html'[source]

Template used to render the add form view.

get_object()[source]

As we are in a add view, no object will be available ever.

get_title()[source]

Generate a sane title when adding new items using the get_model_verbose_name.

class cruditor.views.CruditorChangeView(**kwargs)[source]

Bases: CruditorMixin, FormViewMixin, UpdateView

Enhanced view to edit existing items using a form view.

success_message = 'The {model} "{object}" was successfully changed.'[source]

Message used when a item was changed successfully.

template_name = 'cruditor/form.html'[source]

Template used to render the change form view.

get_title()[source]

Generate a sane title when editing an item using the __str__ representation of a object.

get_delete_url()[source]

Override to provide a link for the delete button in the change view. By default no delete button is visible.

get_context_data(**kwargs)[source]

Add the object_delete_url context variable using get_delete_url. Feel free to extend the context further.

class cruditor.views.CruditorDeleteView(*args, **kwargs)[source]

Bases: CruditorMixin, DeleteView

Enhanced view to delete existing items after a confirmation.

success_message = 'The {model} "{object}" was successfully deleted.'[source]

Message used when a item was deleted.

template_name = 'cruditor/delete.html'[source]

Template used to render the confirmation form view.

delete(*args, **kwargs)[source]

Call the delete() method on the fetched object and then redirect to the success URL.

form_valid(request, *args, **kwargs)[source]

Call perform_delete method and redirect to the success URL with a nice success message. If there are protected related objects, an error message is shown instead with the output of format_linked_objects.

get_title()[source]

Generate a sane title when requesting a confirmation to delete an item using the __str__ representation of a object.

perform_delete()[source]

Actual delete a object/model/item after confirmation.

format_linked_objects(objects)[source]

Generate a list of strings describing the objects which have a protected relation to the item to delete.

class cruditor.views.CruditorChangePasswordView(**kwargs)[source]

Bases: CruditorMixin, FormView

Enhanced view to perform password changes in the Cruditor context.

template_name = 'cruditor/form.html'[source]

Template used when rendering the change password form.

title = 'Change password'[source]

Title for breadcrumb and page.

form_class[source]

Form used to change the password.

alias of ChangePasswordForm

get_form_kwargs()[source]

The current user is passed to the provided form_class when initializing the change password form.

form_valid(form)[source]

Save the new password (by calling form.save) and rotate the session authorization hash.

get_context_data(**kwargs)[source]

Set form_save_button_label context variable to change the button label for the change password form.

class cruditor.views.CruditorLogoutView(**kwargs)[source]

Bases: CruditorMixin, LogoutView

View to log out the current user. After logging out, a info is displayed.

template_name = 'cruditor/logout.html'[source]

Template used to display the info that the user was logged out.

ensure_logged_in(*args, **kwargs)[source]

This method checks if the request user is logged in and has the right flags set (e.g. is_staff if staff_required is set in view).

If user is logged in, True is returned. If not, handle_not_logged_in is called.

get_context_data(**kwargs)[source]

Adds the cruditor context variable to the template context. Uses data from get_cruditor_context method.

Collection

class cruditor.collection.CollectionViewMixin[source]

Bases: object

Mixin to provide some extra default functionality to Cruditor views to make building views for a collection of data (like a Django model) even easier.

collection_list_title = 'Collection'[source]

Title for collection list view

collection_list_urlname = None[source]

URL name to use when linking to the list view (e.g. in breadcrumb)

collection_detail_urlname = None[source]

URL name when linking to a detail page of a item (e.g. in list table or breadcrumb)

get_title()[source]

The method calls the get_collection_list_title method when the view is a list view. All other views rely on the default behavior of cruditor.

get_breadcrumb_title()[source]

The breadcrumb title returns “Delete” for delete views, default breadcrumb for all other views.

get_breadcrumb()[source]

This method creates the required breadcrumb items for the collection following some rules:

  • No extra items for list view

  • list view element when the collection_include_list_crumb method is true.

  • detail view element when the collection_include_detail_crumb method is true.

get_table_class()[source]

This method returns the django-tables2 Table class to use in the list view. If no class is defined, a new Table class is created (with one linked column).

collection_include_list_crumb()[source]

If this method returns true, the list view should be included in the breadcrumb.

collection_include_detail_crumb()[source]

If this method returns true, the detail view should be included in the breadcrumb.

get_collection_list_title()[source]

Helper method to override the used collection list title. By default, just returns the class collection_list_title property.

get_collection_list_url()[source]

Helper method to generate the collection list url. By default, just calls reverse with the collection_list_urlname property.

get_collection_detail_title()[source]

Helper method to override the used collection detail title. By default, just returns the str-representation of the requested item.

get_collection_detail_url()[source]

Helper method to generate the collection detail url for the current object. By default, calls reverse with the collection_detail_urlname property and passes the object pk to the function call.

Changelog

2.4.0 - 2023-02-26

  • Add support for Django 4.1

2.3.3 - 2022-09-19

  • Add more blocks to form template.

2.3.2 - 2022-09-08

  • Expose newForm in formset add callback.

  • Add more template blocks for formset template.

2.3.1 - 2022-08-04

  • Fix issue with logout view

2.3.0 - 2022-08-03

  • Fix issue with small buttons

  • Fix spacing issue with title buttons

  • Add support for target in title buttons.

2.2.0 - 2022-08-02

  • Ship scss and js files with source distribution

  • Add extra blocks for title section for better customization

2.1.0 - 2022-06-23

  • Add get_formset_kwargs method to FormViewMixin

2.0.0 - 2022-05-09

  • Drop support for Django < 2.2

  • Add template_context property for formsets

1.4.0 - 2019-09-26

  • Add method to customize the success message of change form views

1.3.2 - 2019-08-16

  • Improve formset js component

1.3.1 - 2019-08-16

  • Fix issue with formsets and duplicated DELETE inputs

  • Fix broken delete callback in formset js module

1.3.0 - 2019-07-08

  • Catch the exception and show an error message when deleting an item with protected related objects

  • Remove DeleteConfirmForm to replace the checkbox by a simple message and make the deletion process lighter

1.2.1 - 2019-03-26

  • Fix a bug when a user is not logged in but get_titlebuttons/get_breadcrumb relies on self.object

1.2.0 - 2019-03-18

  • Add French translations

  • Improve templates for tables

  • Fix packaging bug when installed as git checkout

  • Fix filter_class related bug in list views

1.1.1 - 2018-08-27

  • Remove local style fix for invalid form inputs, fixed in upstream django-tapeforms

1.1.0 - 2018-08-17

  • Add support for Django 2.1

  • Use auth class based views for login an logout instead of function based views.

1.0.0 - 2018-05-25

  • Many bugfixes and small improvements

  • Add CollectionMixin

  • Add get_titlebuttons helper to add additional buttons to Cruditor views

  • Refactor templates to use UIKit instead of Bootstrap 3

  • Introduce build process for Javascript and CSS files

  • Add support for formsets, including Javascript for the user interface

0.1.4

  • Update translations.

0.1.3

  • Add missing floppyforms load tag.

0.1.2

  • Add floppyforms form tag to inline formset template.

0.1.1

  • Added some useful template blocks.

0.1.0

  • Initial release without many docs but an example project.

Indices and tables