Source code for django_sorcery.views.edit

"""Django edit view things for sqlalchemy."""

from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponseRedirect
from django.views.generic.base import TemplateResponseMixin, View
from django.views.generic.edit import FormMixin

from .. import forms
from .detail import (
    BaseDetailView,
    SingleObjectMixin,
    SingleObjectTemplateResponseMixin,
)


[docs]class ModelFormMixin(FormMixin, SingleObjectMixin): """Provide a way to show and handle a ModelForm in a request.""" fields = None
[docs] def get_form_class(self): if self.fields is not None and self.form_class: raise ImproperlyConfigured("Specifying both 'fields' and 'form_class' is not permitted.") if self.form_class: return self.form_class model = self.get_model() return forms.modelform_factory(model, fields=self.fields, session=self.session)
[docs] def get_form_kwargs(self): """Return the keyword arguments for instantiating the form.""" kwargs = super().get_form_kwargs() if hasattr(self, "object"): kwargs.update({"instance": self.object}) kwargs["session"] = self.session return kwargs
[docs] def get_success_url(self): """Return the URL to redirect to after processing a valid form.""" if self.success_url: return self.success_url.format(**vars(self.object)) raise ImproperlyConfigured( "No URL to redirect to. Either provide a url or override this function to return a url" )
[docs] def form_valid(self, form): self.object = form.save() return super().form_valid(form)
[docs]class ProcessFormView(View): """Render a form on GET and processes it on POST."""
[docs] def get(self, request, *args, **kwargs): """Handle GET requests: instantiate a blank version of the form.""" return self.render_to_response(self.get_context_data())
[docs] def post(self, request, *args, **kwargs): """Handle POST requests: instantiate a form instance with the passed POST variables and then check if it's valid.""" form = self.get_form() if form.is_valid(): return self.form_valid(form) return self.form_invalid(form)
put = post
[docs]class BaseFormView(FormMixin, ProcessFormView): """A base view for displaying a form."""
[docs]class FormView(TemplateResponseMixin, BaseFormView): """A view for displaying a form and rendering a template response."""
[docs]class BaseCreateView(ModelFormMixin, ProcessFormView): """Base view for creating a new object instance. Using this base class requires subclassing to provide a response mixin. """
[docs] def get(self, request, *args, **kwargs): self.object = None return super().get(request, *args, **kwargs)
[docs] def post(self, request, *args, **kwargs): self.object = None return super().post(request, *args, **kwargs)
[docs]class CreateView(SingleObjectTemplateResponseMixin, BaseCreateView): """View for creating a new object, with a response rendered by a template.""" template_name_suffix = "_form"
[docs]class BaseUpdateView(ModelFormMixin, ProcessFormView): """Base view for updating an existing object. Using this base class requires subclassing to provide a response mixin. """
[docs] def get(self, request, *args, **kwargs): self.object = self.get_object() return super().get(request, *args, **kwargs)
[docs] def post(self, request, *args, **kwargs): self.object = self.get_object() return super().post(request, *args, **kwargs)
[docs]class UpdateView(SingleObjectTemplateResponseMixin, BaseUpdateView): """View for updating an object, with a response rendered by a template.""" template_name_suffix = "_form"
[docs]class DeletionMixin: """Provide the ability to delete objects.""" success_url = None
[docs] def delete(self, request, *args, **kwargs): """Call the delete() method on the fetched object and then redirect to the success URL.""" self.object = self.get_object() success_url = self.get_success_url() self.session.delete(self.object) self.session.flush() return HttpResponseRedirect(success_url)
# Add support for browsers which only accept GET and POST for now.
[docs] def post(self, request, *args, **kwargs): """Handle POST request on deleve view.""" return self.delete(request, *args, **kwargs)
[docs] def get_success_url(self): """Returns the URL to redirect to after processing deletion.""" if self.success_url: return self.success_url.format(**self.object.__dict__) else: raise ImproperlyConfigured("No URL to redirect to. Provide a success_url.")
[docs]class BaseDeleteView(DeletionMixin, BaseDetailView): """Base view for deleting an object. Using this base class requires subclassing to provide a response mixin. """
[docs]class DeleteView(SingleObjectTemplateResponseMixin, BaseDeleteView): """View for deleting an object retrieved with self.get_object(), with a response rendered by a template.""" template_name_suffix = "_confirm_delete"