Django uploads: Discard uploaded duplicates, use existing file (md5 based check)

前端 未结 5 2011
别那么骄傲
别那么骄傲 2020-12-07 17:11

I have a model with a FileField, which holds user uploaded files. Since I want to save space, I would like to avoid duplicates.

What I\'d like t

5条回答
  •  萌比男神i
    2020-12-07 17:24

    Data goes from template -> forms -> views -> db(model). It makes sense to stop the duplicates at the earliest step itself. In this case forms.py.

    # scripts.py
    import hashlib
    from .models import *
    def generate_sha(file):
        sha = hashlib.sha1()
        file.seek(0)
        while True:
            buf = file.read(104857600)
            if not buf:
                break
            sha.update(buf)
        sha1 = sha.hexdigest()
        file.seek(0)
        return sha1
    
    # models.py
    class images(models.Model):
        label = models.CharField(max_length=21, blank=False, null=False)
        image = models.ImageField(upload_to='images/')
        image_sha1 = models.CharField(max_length=40, blank=False, null=False)
        create_time = models.DateTimeField(auto_now=True)
    
    # forms.py
    class imageForm(forms.Form):
        Label = forms.CharField(max_length=21, required=True)
        Image = forms.ImageField(required=True)
    
        def clean(self):
            cleaned_data = super(imageForm, self).clean()
            Label = cleaned_data.get('Label')
            Image = cleaned_data.get('Image')
            sha1 = generate_sha(Image)
            if images.objects.filter(image_sha1=sha1).exists():
                raise forms.ValidationError('This already exists')
            if not Label:
                raise forms.ValidationError('No Label')
            if not Image:
                raise forms.ValidationError('No Image')
    
    # views.py
    from .scripts import *
    from .models import *
    from .forms import *
    
    def image(request):
        if request.method == 'POST':
            form = imageForm(request.POST, request.FILES)
            if form.is_valid():
                photo = images (
                    payee=request.user,
                    image=request.FILES['Image'],
                    image_sha1=generate_sha(request.FILES['Image'],),
                    label=form.cleaned_data.get('Label'),
                    )
                photo.save()
                return render(request, 'stars/image_form.html', {'form' : form})
        else:
            form = imageForm()
        context = {'form': form,}
        return render(request, 'stars/image_form.html', context)
    
    # image_form.html
    {% extends "base.html" %}
    {% load static %}
    {% load staticfiles %}
    
    {% block content %}
    
     
    {% csrf_token %} {{ form }}
    {% if form.errors %} {% for field in form %} {% for error in field.errors %}

    {{ error }}

    {% endfor %} {% endfor %} {% endif %}
    {% endblock content %}

    reference: http://josephmosby.com/2015/05/13/preventing-file-dupes-in-django.html

提交回复
热议问题