Reputation: 122432
I have a widget that allows user to enter data for a model field. The data in the form can't be directly converted to Python - it requires some coercion. Where do I put this code? Is the widget responsible for translating its post
data to a python value? The field itself?
I thought that maybe value_from_datadict()
would be correct, but now it looks like that serves a different purpose.
(I'm using the form in the admin interface, if it makes any difference.)
Update @AndiDog: I'm incredulous that to_python
is what I want. From the Django source:
135 def to_python(self, value):
136 """
137 Converts the input value into the expected Python data type, raising
138 django.core.exceptions.ValidationError if the data can't be converted.
139 Returns the converted value. Subclasses should override this.
140 """
141 return value
You're saying that this is called with value
being the POST
data from the form? I put in a print statement, and value
is None
when submitting the form, even though the input has data.
Update 2: Actually, it looks like value_from_datadict
is the way to go. It has a dictionary from names of inputs to their values.
Upvotes: 0
Views: 3145
Reputation:
Quoting the django source for value_from_datadict()
:
Given a dictionary of data and this widget's name, returns the value of this widget. Returns None if it's not provided.
It isn't actually clear what this function is for. Its purpose is to return the value for that widget based on the entire dictionary of posted data; namely, it looks through that data, works out given an instance of the widget which data belongs to it and returns that.
I checked this by crashing my own custom widget with a carefully placed raise
exception.
File "/usr/lib/python2.7/site-packages/django/forms/forms.py" in is_valid
121. return self.is_bound and not bool(self.errors)
File "/usr/lib/python2.7/site-packages/django/forms/forms.py" in _get_errors
112. self.full_clean()
File "/usr/lib/python2.7/site-packages/django/forms/forms.py" in full_clean
267. self._clean_fields()
File "/usr/lib/python2.7/site-packages/django/forms/forms.py" in _clean_fields
278. value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
Do you want to validate here? I did using a multiwidget subclass, but that's not necessarily the best approach. My method re-constructs the date from the dictionary, attempts to create a python date object from it. If this succeeds, it converts it to a string and returns that which is valid; if it doesn't it returns None, which fails validation in the database for the DateField()
type, which is what I wanted to happen.
Whether your widget wants that to happen that way depends on what you're doing. I'm not convinced its the most elegant solution so I'm going to open up my own question...
Refs:
Upvotes: 1
Reputation: 42168
The clean
and clean_<field>
methods in Form subclass are responsible for this. Here are the docs about validation (and cleaning): http://docs.djangoproject.com/en/1.2/ref/forms/validation/
Upvotes: 1