Adding a Cancel button in Django class-based views, editing views and forms
A simple approach to go back from a template
Overview
This a simple approach to add a Cancel button to any form or generic view in Django that uses its class-based views.
Context view
In Django there is a special mixin
django.views.generic.base.ContextMixin
used by most class-based view,
which is responsible of including the keyword arguments into the
template context. But it also includes the proper view in the process
in the variable view
like kwargs.setdefault('view', self)
as
showed in its source code.
class ContextMixin:
"""
A default context mixin that passes the keyword arguments received by
get_context_data() as the template context.
"""
extra_context = None
def get_context_data(self, **kwargs):
kwargs.setdefault('view', self)
if self.extra_context is not None:
kwargs.update(self.extra_context)
return kwargs
ContentMixin
s are used by all of the generic editing views:
django.views.generic.edit.
FormView
,CreateView
,UpdateView
,DeleteView
So we are sure we have the view
in our template context.
Link button
The above view will contain the URL used to redirect after a
successful form submission, available at view.get_success_url
, so we
use that in a Cancel link button like <a href="{{ view.get_success_url }}" class="btn btn-secondary">Cancel</a>
.
In our template:
<form method="post">{% csrf_token %}
....
<input class="btn btn-success" type="submit" value="Save" />
<a href="{{ view.get_success_url }}" class="btn btn-secondary">Cancel</a>
</form>
Special cases
Sometimes your success_url
will be expecting some parameters as for
a newly created item, specially in CreateView
’s, for example:
class EquilangCreatePersonalView(CreateView):
def get_success_url(self):
""" Redirects to the newly created object """
new = self.object
url = reverse_lazy("my-item", kwargs={"pk": new.pk})
return url
In this case we can’t rely on it for the cancel URL, so we just use javascript to get back to the previous page:
<button class="btn btn-link" onclick="javascript:history.back();">Cancel</button>
Explanation
Any HTML
element
has event handler content attributes, in this case we have the
HTML button
element and we use the onclick
event hander to detect when a
user clicks it.
Then we use the javascript History interface.
The History interface allows manipulation of the browser session history, that is the pages visited in the tab or frame that the current page is loaded in.
Specifically the back
method.
This asynchronous method goes to the previous page in session history, the same action as when the user clicks the browser's Back button. Equivalent to history.go(-1).
References
- https://docs.djangoproject.com/en/2.1/ref/class-based-views/mixins-editing/#django.views.generic.edit.FormMixin.success_url
- https://docs.djangoproject.com/en/2.2/ref/class-based-views/mixins-simple/#contextmixin
- https://docs.djangoproject.com/en/2.2/topics/class-based-views/mixins/
- https://developer.mozilla.org/en-US/docs/Web/API/Window/history
- Adding a Cancel button in Django class-based views, editing views and forms
- Using Django Model Primary Key in Custom Forms THE RIGHT WAYJuly 13, 2019
- Django formset handling with class based views, custom errors and validationJuly 4, 2019
- How To Use Bootstrap 4 In Django FormsMay 25, 2018
- Understanding Django FormsApril 30, 2018
- How To Create A Form In DjangoJuly 29, 2016
Articles
Except as otherwise noted, the content of this page is licensed under CC BY-NC-ND 4.0 . Terms and Policy.
Powered by SimpleIT Hugo Theme
·