Need Help with Field Validation

17 views
Skip to first unread message

Mark Phillips

unread,
Dec 3, 2017, 9:44:22 PM12/3/17
to django users
I have a model called Document that has a FileField for uploading files.

class Document(models.Model):
    document_id = models.AutoField(primary_key=True)
    title = models.CharField('title', max_length=200)
    description = models.TextField('description')
    storage_file_name = models.FileField('File name', upload_to=unique_file_path)
    computed_sha256 = models.CharField(editable=False, max_length=64)
    .....

I am trying to validate the storage_file_name field in the Admin form. The validation logic is as follows:

If there is another Document with the same computed_sha256, and this is a new Document, then raise a ValidationError.

The tricky part is the "and this is a new Document". 

In the admin.py, I have a ModelForm called DocumentForm.

class DocumentForm(forms.ModelForm):
    class Meta:
        model = Document
        fields = "__all__" 
        
    def clean_storage_file_name(self):
        cleaned_data = self.cleaned_data
        computed_sha256 = compute_sha256(cleaned_data.get("storage_file_name"))
        duplicates = Document.objects.filter(computed_sha256__exact=computed_sha256)
        current_doc_id = cleaned_data.get('document_id')
        for d in duplicates:
            if (existing_doc_id != d.document_id):
                raise forms.ValidationError("The image '%s' is already in the database" % (cleaned_data.get("storage_file_name")))
        return self.cleaned_data['storage_file_name']

The current_doc_id is always None, whether I am uploading a new file or I am editing a current file already in the database. I can read all the other document fields, but not the document_id field. If I am updating an existing document, then the current_document_id should exist and be equal to the d.document_id (the id of the document found in the search).

I can't figure out why the current_document_id is always None. What am I missing here?

How else can I block the ValidationError when I am merely updating another Document field, because that also returns a duplicate image based on the computed_sha256.

Thanks!

Mark



Mark Phillips

unread,
Dec 4, 2017, 3:15:35 PM12/4/17
to django users
I found my error after some more reading...The corrected clean_storage_file_name(self)

    def clean_storage_file_name(self):
        current_data = self.instance
        computed_sha256 = compute_sha256(self.cleaned_data.get("storage_file_name"))
        duplicates = Document.objects.filter(computed_sha256__exact=computed_sha256)
        for d in duplicates:
            if (current_data.document_id != d.document_id):
                # new document that is already in database, just updating the information so save it.
                raise forms.ValidationError("The image '%s' is already in the database" % (self.cleaned_data.get("storage_file_name")))
        return self.cleaned_data['storage_file_name']

I had to use self.instance to get the document_id of the object returned to the form, and self.cleaned_data.get("....") to access the other fields in the returned data. No idea why, but it works now!

Can someone explain the difference between self.cleaned_data and self.instance in a ModelForm?

Thanks!

Mark
Reply all
Reply to author
Forward
0 new messages