Created
July 3, 2014 03:06
-
-
Save anonymous/953e569362f2936ec9a4 to your computer and use it in GitHub Desktop.
Bind an object (through a hidden field) to a form
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 FormHiddenObjectMixin(object): | |
""" | |
In forms in various create and update views, some of the form values | |
are populated and hiddedn when the form is created. The user does not | |
have to fill in this field. For example, when creating a shipment, we | |
know that is for a particular purchase order. The purchase_order | |
parameter of the form is set during form initialization. | |
This mixin provides support for finding this related object either from | |
URL query parameters (in the case of a CreateView) or from the object | |
itself (in the case of an UpdateView). | |
""" | |
hidden_object_model = None | |
hidden_object_context_name = '' | |
hidden_object_pk_query_param = '' | |
hidden_object_field_name = '' | |
hidden_object = None | |
def get_hidden_object(self): | |
if not self.hidden_object: | |
self.hidden_object = self.get_hidden_object_from_object() or self.get_hidden_object_from_url() | |
return self.hidden_object | |
def get_hidden_object_from_object(self): | |
if not self.object: | |
return None | |
if not self.hidden_object_field_name: | |
raise ImproperlyConfigured( | |
"FormHiddenObjectMixin requires the definition of 'hidden_object_field_name'") | |
return getattr(self.object, self.hidden_object_field_name) | |
def get_hidden_object_from_url(self): | |
if not (self.hidden_object_pk_query_param and self.hidden_object_model): | |
raise ImproperlyConfigured( | |
"FormHiddenObjectMixin requires the definition of 'hidden_object_pk_query_param'" | |
" and 'hidden_object_model'") | |
pk = self.request.GET.get(self.hidden_object_pk_query_param, None) | |
obj = get_object_or_404(self.hidden_object_model, pk=pk) | |
return obj | |
def get_hidden_initial_form_data(self): | |
if not self.hidden_object_field_name: | |
raise ImproperlyConfigured( | |
"FormHiddenObjectMixin requires the definition of 'hidden_object_field_name'") | |
return { | |
self.hidden_object_field_name: self.get_hidden_object(), | |
} | |
def get_hidden_context_data(self): | |
if not self.hidden_object_context_name: | |
raise ImproperlyConfigured( | |
"FormHiddenObjectMixin requires the definition of 'hidden_object_context_name'") | |
return { | |
self.hidden_object_context_name: self.get_hidden_object(), | |
} | |
class PictureFormHiddenObjectMixin(FormHiddenObjectMixin): | |
hidden_object_context_name = 'client' | |
hidden_object_field_name = 'client' | |
hidden_object_pk_query_param = 'client_pk' | |
hidden_object_model = Client | |
class PictureCreate(PictureFormHiddenObjectMixin, CreateView): | |
model = Picture | |
form_class = modelform_factory(Picture, | |
widgets={ 'client': forms.HiddenInput() }, | |
fields=('pic', 'client', )) | |
def get_initial(self): | |
initial = super(PictureCreate, self).get_initial() | |
initial.update(self.get_hidden_initial_form_data()) | |
return initial | |
def get_context_data(self, **kwargs): | |
context = super(PictureCreate, self).get_context_data(**kwargs) | |
context.update(self.get_hidden_context_data()) | |
return context | |
# My URL looks like example.com/upload?client_pk=3 | |
# You could change the URL to example.com/client/3/upload/ as well. You'd have to slightly | |
# change the logic in get_hidden_object_from_url() to get it from self.kwargs | |
# rather than from the query parameter |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment