Skip to content

Instantly share code, notes, and snippets.

@frague59
Created June 13, 2016 11:13
Show Gist options
  • Save frague59/fe729691bfe41ab26eef1d6de859256f to your computer and use it in GitHub Desktop.
Save frague59/fe729691bfe41ab26eef1d6de859256f to your computer and use it in GitHub Desktop.
Formset mixin
class InlineFormsetMixin(SingleObjectTemplateResponseMixin, BaseFormsetMixin):
object = None
formset_link_field = None
def get_formset_kwargs(self):
"""
Gets the formset kwargs
:returns: dict of kwargs
"""
kwargs = {'initial': self.get_formset_initial()}
if hasattr(self, 'get_formset_prefix'):
kwargs.update({'prefix': self.get_formset_prefix()})
if hasattr(self, 'get_object') and hasattr(self, 'get_queryset'):
kwargs.update({'instance': self.get_object(queryset=self.get_queryset())})
if self.request.method in ('POST', 'PUT'):
kwargs.update({'files': self.request.FILES, 'data': self.request.POST})
settings.DEBUG and logger.debug(u'InlineFormsetMixin::get_formset_kwargs() %s kwargs = %s', self.request.method,
unicode(repr(kwargs), errors='replace'))
return kwargs
def get_formset(self, formset_class=None, data=None):
"""
Gets the current formset instance
:param formset_class: formset class
:param data: data from request
:returns: formset instance
"""
#
# if self._formset_instance:
# settings.DEBUG and logger.debug(u'InlineFormsetMixin::get_formset() already initialized.')
# return self._formset_instance
formset_class = formset_class or self.get_formset_class()
self._formset_instance = formset_class(**self.get_formset_kwargs())
return self._formset_instance
def get_formset_link_field(self):
if self.formset_link_field:
return self.formset_link_field
raise ImproperlyConfigured(u'%s MUST implement a formset_link_field attribute !' % self.__class__.__name__)
def form_valid(self, form=None, formset=None):
"""
Form and Formset are valid : redirect if **NOT** continuable
:param form: current form
:type form: Form
:param formset: current formset
:type formset: Formset
:returns: tuple (saved object, list of formset objects)
"""
settings.DEBUG and logger.debug(u'InlineFormsetMixin::form_valid() form and formset are valid !')
if hasattr(self, 'get_object') and hasattr(self, 'get_queryset'):
self.object = self.get_object(self.get_queryset())
# Gets the form instance
form = form or self.get_form()
# # Loads the changed data
changed_data = form.changed_data
self.object = form.save(commit=True)
# Gets the formset instance
formset = formset or getattr(self, 'formset', None) or self.get_formset()
settings.DEBUG and logger.debug(u'InlineFormsetMixin::form_valid() form.instance= *%s*'
u'\nform.changed_data = %s', form.instance, changed_data)
linked_instance_list = []
formset_link_field = self.get_formset_link_field()
for formset_form in formset.forms:
if formset_form.has_changed() and formset_form.is_valid():
if 'DELETE' in formset_form.changed_data:
formset_form.instance.delete()
continue
linked_instance = formset_form.save(commit=False)
try:
if hasattr(linked_instance, formset_link_field):
setattr(linked_instance, formset_link_field, self.object)
linked_instance.save() # Save / commit instance !
except Exception as e:
logger.warning(u'InlineFormsetMixin::form_valid() Unable to save formset form instance : %s', e)
linked_instance_list.append(linked_instance)
# Redirecting to view
url = self._get_continuable_success_url()
settings.DEBUG and logger.debug(u'InlineFormsetMixin::form_valid() '
u'object = %s / linked_instance_list = %s\nurl = %s',
self.object, unicode(repr(linked_instance_list), errors='ignore'), url)
return redirect(url)
def form_invalid(self, form=None, formset=None):
"""
Action to perform is form is invalid
:param form: parent form
:param formset: formset
:returns: current view with error messages
"""
form = form or self.get_form()
# formset = formset or self.get_formset()
return super(InlineFormsetMixin, self).form_invalid(form)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment