I instantiate a ModelForm
based on some input data
, and then I generate/fetch some new data based on that input data, and want to refresh my ModelForm
with the new data and then save it afterwards.
I would rather like to use ModelForm
s as much as possible and avoid having to interact with the associated Model
object directly when it comes to saving/validation and other stuff (e.g. white-space trimming).
One solution would be to instantiate another new ModelForm
based on the new (and the previous) data and feeding the constructor the generated Model
object via instance
argument, then save()
again!
But, is there another better/neater/more optimized way, without having to instantiate two ModelForm
s?
[app].models.py:
from django.db import models
from .custom_fields import HTTPURLField
from .function_validators import validate_md5
class Snapshot(models.Model):
url = HTTPURLField(max_length=1999)
content_hash = models.CharField(max_length=32, default='00000000000000000000000000000000',
validators=[validate_md5])
timestamp = models.DateTimeField(auto_now=True)
[app].forms.py:
from django import forms
from .models import Snapshot
class SnapshotModelForm(forms.ModelForm):
class Meta:
model = Snapshot
fields = ('url', 'content_hash')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['content_hash'].required = False
[app].views.py:
from django.http import HttpResponse
from .forms import SnapshotModelForm
def index(request):
snapshot_form = SnapshotModelForm(
data={'url': ' http://www.baidu.com/ '})
try:
model_instance = snapshot_form.save(commit=False)
generated_new_content_hash = ' 21111111121111111111111111111111 ' # or calculate it from given data! generated_new_content_hash = newdata(model_instance.url)
snapshot_form2 = SnapshotModelForm(instance=model_instance,
data={'url': model_instance.url,
'content_hash': generated_new_content_hash })
snapshot_form2.save()
return HttpResponse("Saved")
except ValueError:
return HttpResponse("Not Saved")
In the code above I hard-coded the value of the new "generated/fetched" data for more readability: generated_new_content_hash=' 21111111121111111111111111111111 '
You don't need to resave the form, you can add the value in a clean_content_hash()
method directly on the form: https://docs.djangoproject.com/en/4.1/ref/forms/validation/#form-and-field-validation
class SnapshotModelForm(forms.ModelForm):
def clean_content_hash(self):
data = self.cleaned_data['content_hash']
if not data:
data = generated_new_content_hash()
return data