diff options
Diffstat (limited to 'lib/python2.7/site-packages/django/views/generic/edit.py')
-rw-r--r-- | lib/python2.7/site-packages/django/views/generic/edit.py | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/lib/python2.7/site-packages/django/views/generic/edit.py b/lib/python2.7/site-packages/django/views/generic/edit.py new file mode 100644 index 0000000..fccacf0 --- /dev/null +++ b/lib/python2.7/site-packages/django/views/generic/edit.py @@ -0,0 +1,280 @@ +import warnings + +from django.forms import models as model_forms +from django.core.exceptions import ImproperlyConfigured +from django.http import HttpResponseRedirect +from django.utils.encoding import force_text +from django.views.generic.base import TemplateResponseMixin, ContextMixin, View +from django.views.generic.detail import (SingleObjectMixin, + SingleObjectTemplateResponseMixin, BaseDetailView) + + +class FormMixin(ContextMixin): + """ + A mixin that provides a way to show and handle a form in a request. + """ + + initial = {} + form_class = None + success_url = None + prefix = None + + def get_initial(self): + """ + Returns the initial data to use for forms on this view. + """ + return self.initial.copy() + + def get_prefix(self): + """ + Returns the prefix to use for forms on this view + """ + return self.prefix + + def get_form_class(self): + """ + Returns the form class to use in this view + """ + return self.form_class + + def get_form(self, form_class): + """ + Returns an instance of the form to be used in this view. + """ + return form_class(**self.get_form_kwargs()) + + def get_form_kwargs(self): + """ + Returns the keyword arguments for instantiating the form. + """ + kwargs = { + 'initial': self.get_initial(), + 'prefix': self.get_prefix(), + } + + if self.request.method in ('POST', 'PUT'): + kwargs.update({ + 'data': self.request.POST, + 'files': self.request.FILES, + }) + return kwargs + + def get_success_url(self): + """ + Returns the supplied success URL. + """ + if self.success_url: + # Forcing possible reverse_lazy evaluation + url = force_text(self.success_url) + else: + raise ImproperlyConfigured( + "No URL to redirect to. Provide a success_url.") + return url + + def form_valid(self, form): + """ + If the form is valid, redirect to the supplied URL. + """ + return HttpResponseRedirect(self.get_success_url()) + + def form_invalid(self, form): + """ + If the form is invalid, re-render the context data with the + data-filled form and errors. + """ + return self.render_to_response(self.get_context_data(form=form)) + + +class ModelFormMixin(FormMixin, SingleObjectMixin): + """ + A mixin that provides a way to show and handle a modelform in a request. + """ + fields = None + + def get_form_class(self): + """ + Returns the form class to use in this view. + """ + if self.form_class: + return self.form_class + else: + if self.model is not None: + # If a model has been explicitly provided, use it + model = self.model + elif hasattr(self, 'object') and self.object is not None: + # If this view is operating on a single object, use + # the class of that object + model = self.object.__class__ + else: + # Try to get a queryset and extract the model class + # from that + model = self.get_queryset().model + + if self.fields is None: + warnings.warn("Using ModelFormMixin (base class of %s) without " + "the 'fields' attribute is deprecated." % self.__class__.__name__, + PendingDeprecationWarning) + + return model_forms.modelform_factory(model, fields=self.fields) + + def get_form_kwargs(self): + """ + Returns the keyword arguments for instantiating the form. + """ + kwargs = super(ModelFormMixin, self).get_form_kwargs() + kwargs.update({'instance': self.object}) + return kwargs + + def get_success_url(self): + """ + Returns the supplied URL. + """ + if self.success_url: + url = self.success_url % self.object.__dict__ + else: + try: + url = self.object.get_absolute_url() + except AttributeError: + raise ImproperlyConfigured( + "No URL to redirect to. Either provide a url or define" + " a get_absolute_url method on the Model.") + return url + + def form_valid(self, form): + """ + If the form is valid, save the associated model. + """ + self.object = form.save() + return super(ModelFormMixin, self).form_valid(form) + + +class ProcessFormView(View): + """ + A mixin that renders a form on GET and processes it on POST. + """ + def get(self, request, *args, **kwargs): + """ + Handles GET requests and instantiates a blank version of the form. + """ + form_class = self.get_form_class() + form = self.get_form(form_class) + return self.render_to_response(self.get_context_data(form=form)) + + def post(self, request, *args, **kwargs): + """ + Handles POST requests, instantiating a form instance with the passed + POST variables and then checked for validity. + """ + form_class = self.get_form_class() + form = self.get_form(form_class) + if form.is_valid(): + return self.form_valid(form) + else: + return self.form_invalid(form) + + # PUT is a valid HTTP verb for creating (with a known URL) or editing an + # object, note that browsers only support POST for now. + def put(self, *args, **kwargs): + return self.post(*args, **kwargs) + + +class BaseFormView(FormMixin, ProcessFormView): + """ + A base view for displaying a form + """ + + +class FormView(TemplateResponseMixin, BaseFormView): + """ + A view for displaying a form, and rendering a template response. + """ + + +class BaseCreateView(ModelFormMixin, ProcessFormView): + """ + Base view for creating an new object instance. + + Using this base class requires subclassing to provide a response mixin. + """ + def get(self, request, *args, **kwargs): + self.object = None + return super(BaseCreateView, self).get(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + self.object = None + return super(BaseCreateView, self).post(request, *args, **kwargs) + + +class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView): + """ + View for creating a new object instance, + with a response rendered by template. + """ + template_name_suffix = '_form' + + +class BaseUpdateView(ModelFormMixin, ProcessFormView): + """ + Base view for updating an existing object. + + Using this base class requires subclassing to provide a response mixin. + """ + def get(self, request, *args, **kwargs): + self.object = self.get_object() + return super(BaseUpdateView, self).get(request, *args, **kwargs) + + def post(self, request, *args, **kwargs): + self.object = self.get_object() + return super(BaseUpdateView, self).post(request, *args, **kwargs) + + +class UpdateView(SingleObjectTemplateResponseMixin, BaseUpdateView): + """ + View for updating an object, + with a response rendered by template. + """ + template_name_suffix = '_form' + + +class DeletionMixin(object): + """ + A mixin providing the ability to delete objects + """ + success_url = None + + def delete(self, request, *args, **kwargs): + """ + Calls the delete() method on the fetched object and then + redirects to the success URL. + """ + self.object = self.get_object() + success_url = self.get_success_url() + self.object.delete() + return HttpResponseRedirect(success_url) + + # Add support for browsers which only accept GET and POST for now. + def post(self, request, *args, **kwargs): + return self.delete(request, *args, **kwargs) + + def get_success_url(self): + if self.success_url: + return self.success_url % self.object.__dict__ + else: + raise ImproperlyConfigured( + "No URL to redirect to. Provide a success_url.") + + +class BaseDeleteView(DeletionMixin, BaseDetailView): + """ + Base view for deleting an object. + + Using this base class requires subclassing to provide a response mixin. + """ + + +class DeleteView(SingleObjectTemplateResponseMixin, BaseDeleteView): + """ + View for deleting an object retrieved with `self.get_object()`, + with a response rendered by template. + """ + template_name_suffix = '_confirm_delete' |