Login

Unique FileFiled or FileFiled with custom validation and overwriting files on update

Author:
evilclay
Posted:
January 15, 2011
Language:
Python
Version:
1.2
Score:
2 (after 2 ratings)

I needed to overwrite files on update (not create new ones) but also a validation which would prevent to upload 2 files with the same name.

The CustomCheckFiled triggers a validation passing the filename and model instance. If the validation returns false, the validation error_message will be displayed in admin.

The OverwriteStorage is needed because the default storage alters the name if such name already exists. Enjoy.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# extra py - The Custom FileFiled

from django.db.models import FileField
from django.forms import forms

class CustomCheckFileField(FileField):
    def __init__(self, custom_check=None, error_message=None, **kwargs):

        self.error_message=error_message

        if callable(custom_check):
            self.custom_check = custom_check

        super(CustomCheckFileField, self).__init__(**kwargs)

    def clean(self, *args, **kwargs):
        data = super(CustomCheckFileField, self).clean(*args, **kwargs)

        file = data.file

        #args[1] is the model instance
        if not self.custom_check(args[1], self.generate_filename(args[1], file.name)):
            raise forms.ValidationError(self.error_message)
        return data

    def custom_check(self, filename):
        return True



#custom FileSystemStorage which return same name for existing file (also deletes existing files on save
#some_other.py
from django.core.files.storage import FileSystemStorage

class OverwriteStorage(FileSystemStorage):

    def _save(self, name, content):
        if self.exists(name):
            self.delete(name)
        return super(OverwriteStorage, self)._save(name, content)

    def get_available_name(self, name):
        return name


#usage
#models.py

def _custom_media_file_unique(instance, filename):
    existing = CustomMedia.objects.filter(file=filename)
    if existing and existing.count() > 1:
        return False
    else:
        if existing:
            return existing[0].id == instance.id
    return True

class CustomMedia(models.Model):
    file = CustomCheckFileField(upload_to=_get_media_upload_to, custom_check=_custom_media_file_unique,error_message="File Already Exists",storage=OverwriteStorage())

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 2 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 2 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 9 months, 2 weeks ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 10 months, 1 week ago
  5. Help text hyperlinks by sa2812 11 months ago

Comments

Please login first before commenting.