Last active
September 16, 2015 13:40
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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