Reputation: 2350
I am using Django's forms to validate API PATCH requests. In the "view" (which I use in quotes because it isn't really a view directly, it is a restless Resource
, but that should be irrelevant here) which handles this patch request, self.data
contains a dictionary of changes to some of the fields of the License
object. I want to instantiate a ModelForm
with the instance of the object to be changed. Clearly, though, I am misunderstanding how this works. See below:
def handle_patch(self, pk):
license = License.objects.get(id=pk)
form = LicenseResourceForm(self.data, instance=license)
if not form.is_valid():
print(form.errors)
If I pass a few fields as data to the above function, form.errors
complains about every other required field of the License
model, meaning I'm clearly not understanding how setting an instance on a ModelForm
works.
I added a few debug prints to Django's ModelForm
code itself in the clean()
method, and as it begins to do the cleaning process, I can see that self.instance
is populated with the instance of License
that I expect, which confuses me - the ModelForm
object knows the instance, but isn't using it to "fill in the blanks" so to speak.
So what am I misunderstanding? I must be doing this wrong.
EDIT I realize that some of you may want to see the LicenseResourceForm
itself, so here it is, including my debug print:
class LicenseResourceForm(ModelForm):
"""Form for License Resource create and change endpoints."""
class Meta(object):
model = License
fields = ['customer', 'service', 'enabled', 'not_valid_before', 'not_valid_after']
def clean(self):
try:
print(self.instance)
super().clean()
except Exception as e:
print(e)
Upvotes: 0
Views: 202
Reputation: 599490
Django forms aren't meant for API use and don't understand PATCH semantics. They are meant for the workflow of a user entering or changing data in a web form, which will always post all the data to the backend. Therefore, all fields listed in the fields
attribute of the form will be checked against the data, and any missing fields will be validated as blank.
You could probably fix this by doing something clever to dynamically set the list of fields based on the data supplied, but really you should use the appropriate tool for validating your data. I don't know restless, but django-rest-framework has serializers which can be used for this.
Upvotes: 1