pythondjangomodelform

How to re-save a ModelForm?


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 ModelForms 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 ModelForms?

[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 '


Solution

  • 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