I\'ve got a Form
. I want to include a hidden field that returns a model. I\'ll set it\'s value in the view; I just need it to be posted along to the next page.
The approach in Yuji's answer uses a clean_model_instance
method on the form which is fine if you're only ever doing this once in your code base. If you do it more often, then you might benefit from implementing a custom model field.
This is the code I have:
from django import forms
class ModelField(forms.Field):
Model = None
def prepare_value(self, value):
"""Inject entities' id value into the form's html data"""
if isinstance(value, self.Model):
return value.id
return value
def to_python(self, value):
"""More or less stolen from ModelChoiceField.to_python"""
if value in self.empty_values:
return None
try:
value = self.Model.objects.get(id=value)
except (ValueError, self.Model.DoesNotExist):
raise forms.ValidationError('%s does not exist'
% self.Model.__class__.__name__.capitalize())
return value
If you use that as a base class and then specialise it with your own models then it becomes a useful based. For example:
# In app/fields.py
from .models import CustomModel
class CustomModelField(ModelField):
Model = CustomModel
Then you can pair that with whatever widget you need at the time:
# in app/forms.py
class MyForm(forms.Form):
hidden_custom_model_field = CustomModelField(widget=forms.HiddenInput())
other_widget_custom_model_field = CustomModelField(widget=MyCustomWidget())