1 from django
.forms
import models
as model_forms
2 from django
.core
.exceptions
import ImproperlyConfigured
3 from django
.http
import HttpResponseRedirect
4 from django
.views
.generic
.base
import TemplateResponseMixin
, View
5 from django
.views
.generic
.detail
import (SingleObjectMixin
,
6 SingleObjectTemplateResponseMixin
, BaseDetailView
)
9 class FormMixin(object):
11 A mixin that provides a way to show and handle a form in a request.
18 def get_initial(self
):
20 Returns the initial data to use for forms on this view.
22 return self
.initial
.copy()
24 def get_form_class(self
):
26 Returns the form class to use in this view
28 return self
.form_class
30 def get_form(self
, form_class
):
32 Returns an instance of the form to be used in this view.
34 return form_class(**self
.get_form_kwargs())
36 def get_form_kwargs(self
):
38 Returns the keyword arguments for instanciating the form.
40 kwargs
= {'initial': self
.get_initial()}
41 if self
.request
.method
in ('POST', 'PUT'):
43 'data': self
.request
.POST
,
44 'files': self
.request
.FILES
,
48 def get_context_data(self
, **kwargs
):
51 def get_success_url(self
):
53 url
= self
.success_url
55 raise ImproperlyConfigured(
56 "No URL to redirect to. Provide a success_url.")
59 def form_valid(self
, form
):
60 return HttpResponseRedirect(self
.get_success_url())
62 def form_invalid(self
, form
):
63 return self
.render_to_response(self
.get_context_data(form
=form
))
66 class ModelFormMixin(FormMixin
, SingleObjectMixin
):
68 A mixin that provides a way to show and handle a modelform in a request.
71 def get_form_class(self
):
73 Returns the form class to use in this view
76 return self
.form_class
78 if self
.model
is not None:
79 # If a model has been explicitly provided, use it
81 elif hasattr(self
, 'object') and self
.object is not None:
82 # If this view is operating on a single object, use
83 # the class of that object
84 model
= self
.object.__class
__
86 # Try to get a queryset and extract the model class
88 model
= self
.get_queryset().model
89 return model_forms
.modelform_factory(model
)
91 def get_form_kwargs(self
):
93 Returns the keyword arguments for instanciating the form.
95 kwargs
= super(ModelFormMixin
, self
).get_form_kwargs()
96 kwargs
.update({'instance': self
.object})
99 def get_success_url(self
):
101 url
= self
.success_url
% self
.object.__dict
__
104 url
= self
.object.get_absolute_url()
105 except AttributeError:
106 raise ImproperlyConfigured(
107 "No URL to redirect to. Either provide a url or define"
108 " a get_absolute_url method on the Model.")
111 def form_valid(self
, form
):
112 self
.object = form
.save()
113 return super(ModelFormMixin
, self
).form_valid(form
)
115 def get_context_data(self
, **kwargs
):
118 context
['object'] = self
.object
119 context_object_name
= self
.get_context_object_name(self
.object)
120 if context_object_name
:
121 context
[context_object_name
] = self
.object
125 class ProcessFormView(View
):
127 A mixin that processes a form on POST.
129 def get(self
, request
, *args
, **kwargs
):
130 form_class
= self
.get_form_class()
131 form
= self
.get_form(form_class
)
132 return self
.render_to_response(self
.get_context_data(form
=form
))
134 def post(self
, request
, *args
, **kwargs
):
135 form_class
= self
.get_form_class()
136 form
= self
.get_form(form_class
)
138 return self
.form_valid(form
)
140 return self
.form_invalid(form
)
142 # PUT is a valid HTTP verb for creating (with a known URL) or editing an
143 # object, note that browsers only support POST for now.
144 def put(self
, *args
, **kwargs
):
145 return self
.post(*args
, **kwargs
)
148 class BaseFormView(FormMixin
, ProcessFormView
):
150 A base view for displaying a form
154 class FormView(TemplateResponseMixin
, BaseFormView
):
156 A view for displaying a form, and rendering a template response.
160 class BaseCreateView(ModelFormMixin
, ProcessFormView
):
162 Base view for creating an new object instance.
164 Using this base class requires subclassing to provide a response mixin.
166 def get(self
, request
, *args
, **kwargs
):
168 return super(BaseCreateView
, self
).get(request
, *args
, **kwargs
)
170 def post(self
, request
, *args
, **kwargs
):
172 return super(BaseCreateView
, self
).post(request
, *args
, **kwargs
)
175 class CreateView(SingleObjectTemplateResponseMixin
, BaseCreateView
):
177 View for creating an new object instance,
178 with a response rendered by template.
180 template_name_suffix
= '_form'
183 class BaseUpdateView(ModelFormMixin
, ProcessFormView
):
185 Base view for updating an existing object.
187 Using this base class requires subclassing to provide a response mixin.
189 def get(self
, request
, *args
, **kwargs
):
190 self
.object = self
.get_object()
191 return super(BaseUpdateView
, self
).get(request
, *args
, **kwargs
)
193 def post(self
, request
, *args
, **kwargs
):
194 self
.object = self
.get_object()
195 return super(BaseUpdateView
, self
).post(request
, *args
, **kwargs
)
198 class UpdateView(SingleObjectTemplateResponseMixin
, BaseUpdateView
):
200 View for updating an object,
201 with a response rendered by template..
203 template_name_suffix
= '_form'
206 class DeletionMixin(object):
208 A mixin providing the ability to delete objects
212 def delete(self
, request
, *args
, **kwargs
):
213 self
.object = self
.get_object()
215 return HttpResponseRedirect(self
.get_success_url())
217 # Add support for browsers which only accept GET and POST for now.
218 def post(self
, *args
, **kwargs
):
219 return self
.delete(*args
, **kwargs
)
221 def get_success_url(self
):
223 return self
.success_url
225 raise ImproperlyConfigured(
226 "No URL to redirect to. Provide a success_url.")
229 class BaseDeleteView(DeletionMixin
, BaseDetailView
):
231 Base view for deleting an object.
233 Using this base class requires subclassing to provide a response mixin.
237 class DeleteView(SingleObjectTemplateResponseMixin
, BaseDeleteView
):
239 View for deleting an object retrieved with `self.get_object()`,
240 with a response rendered by template.
242 template_name_suffix
= '_confirm_delete'