Skip to content

Instantly share code, notes, and snippets.

@eugena
Last active September 16, 2015 13:40
Show Gist options
  • Save eugena/37ca184beac050615b1a to your computer and use it in GitHub Desktop.
Save eugena/37ca184beac050615b1a to your computer and use it in GitHub Desktop.
The prototype of BaseFormView when form rendering executes in one layer, but validation and object saving in another
class PrototypeOfBaseView(FormView):
"""
The prototype of base view, which allows to render a form
by Django Form framework, but to validate and save data by API framework
"""
template_name = None
serializer_class = None
fields = None
success_url = None
def get_form_class(self, form_class=None):
"""
Returns the form object
"""
if self.fields is None:
raise ImproperlyConfigured(
"Using PrototypeOfBaseView (base class of %s) without "
"the 'fields' attribute is prohibited." % self.__class__.__name__
)
return model_forms.modelform_factory(model=self.serializer_class.Meta.model, fields=self.fields)
def get_serializer(self, data):
"""
Return the class to use for the serializer.
Defaults to using `self.serializer_class`.
May be to override this if you need to provide different
serializations depending on the incoming request.
"""
assert self.serializer_class is not None, (
"'%s' should either include a `serializer_class` attribute, "
"or override the `get_serializer_class()` method."
% self.__class__.__name__
)
self.serializer_class.Meta.fields = self.fields
return self.serializer_class(data=data)
def get(self, request, *args, **kwargs):
"""
Handles GET requests and instantiates a blank version of the form.
"""
return self.render_to_response(self.get_context_data(form=self.get_form()))
def serializer_valid(self, serializer):
"""
If the serializer is valid, save the associated model.
"""
self.object = serializer.save()
return HttpResponseRedirect(self.get_success_url())
def post(self, request, *args, **kwargs):
"""
Handles POST requests, instantiating a serializer instance with the passed
POST variables and then checked for validity.
"""
serializer = self.get_serializer(data=request.POST)
if serializer.is_valid():
return self.serializer_valid(serializer)
else:
form = self.get_form()
form.full_clean()
return self.form_invalid(form)
class BaseAPIView(GenericAPIView):
"""
Base API View with ability to remove the fields which are absent in data from a serializer
and thus turn validation of them off
"""
def get_serializer(self, *args, **kwargs):
"""
Returns the serializer object
"""
serializer_class = self.get_serializer_class()
if 'data' in kwargs.keys():
serializer_fields = self.serializer_class.Meta.fields
serializer_class.Meta.fields = list(set(serializer_fields) & set(list(kwargs['data'])))
kwargs['context'] = self.get_serializer_context()
return serializer_class(*args, **kwargs)
class BaseAPIViewSet(ViewSetMixin, BaseAPIView):
"""
Base API Viewset
"""
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment