mirror of
				https://gitlab.crans.org/bde/nk20
				synced 2025-11-03 17:08:47 +01:00 
			
		
		
		
	Move image upload code to form clean
This commit is contained in:
		@@ -1,7 +1,11 @@
 | 
				
			|||||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
 | 
					# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
 | 
				
			||||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
					# SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import io
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from PIL import Image
 | 
				
			||||||
from django import forms
 | 
					from django import forms
 | 
				
			||||||
 | 
					from django.conf import settings
 | 
				
			||||||
from django.contrib.auth.forms import AuthenticationForm
 | 
					from django.contrib.auth.forms import AuthenticationForm
 | 
				
			||||||
from django.contrib.auth.models import User
 | 
					from django.contrib.auth.models import User
 | 
				
			||||||
from django.forms import CheckboxSelectMultiple
 | 
					from django.forms import CheckboxSelectMultiple
 | 
				
			||||||
@@ -77,6 +81,38 @@ class ImageForm(forms.Form):
 | 
				
			|||||||
    width = forms.FloatField(widget=forms.HiddenInput())
 | 
					    width = forms.FloatField(widget=forms.HiddenInput())
 | 
				
			||||||
    height = forms.FloatField(widget=forms.HiddenInput())
 | 
					    height = forms.FloatField(widget=forms.HiddenInput())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clean(self):
 | 
				
			||||||
 | 
					        """Load image and crop"""
 | 
				
			||||||
 | 
					        cleaned_data = super().clean()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Image size is limited by Django DATA_UPLOAD_MAX_MEMORY_SIZE
 | 
				
			||||||
 | 
					        image = cleaned_data.get('image')
 | 
				
			||||||
 | 
					        if image:
 | 
				
			||||||
 | 
					            # Let Pillow detect and load image
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                im = Image.open(image)
 | 
				
			||||||
 | 
					            except OSError:
 | 
				
			||||||
 | 
					                # Rare case in which Django consider the upload file as an image
 | 
				
			||||||
 | 
					                # but Pil is unable to load it
 | 
				
			||||||
 | 
					                raise forms.ValidationError(_('This image cannot be loaded.'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Crop image
 | 
				
			||||||
 | 
					            x = cleaned_data.get('x', 0)
 | 
				
			||||||
 | 
					            y = cleaned_data.get('y', 0)
 | 
				
			||||||
 | 
					            w = cleaned_data.get('width', 200)
 | 
				
			||||||
 | 
					            h = cleaned_data.get('height', 200)
 | 
				
			||||||
 | 
					            im = im.crop((x, y, x + w, y + h))
 | 
				
			||||||
 | 
					            im = im.resize(
 | 
				
			||||||
 | 
					                (settings.PIC_WIDTH, settings.PIC_RATIO * settings.PIC_WIDTH),
 | 
				
			||||||
 | 
					                Image.ANTIALIAS,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Save
 | 
				
			||||||
 | 
					            image.file = io.BytesIO()
 | 
				
			||||||
 | 
					            im.save(image.file, "PNG")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return cleaned_data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ClubForm(forms.ModelForm):
 | 
					class ClubForm(forms.ModelForm):
 | 
				
			||||||
    def clean(self):
 | 
					    def clean(self):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,8 @@
 | 
				
			|||||||
# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
 | 
					# Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
 | 
				
			||||||
# SPDX-License-Identifier: GPL-3.0-or-later
 | 
					# SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import io
 | 
					 | 
				
			||||||
from datetime import timedelta, date
 | 
					from datetime import timedelta, date
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from PIL import Image
 | 
					 | 
				
			||||||
from django.conf import settings
 | 
					from django.conf import settings
 | 
				
			||||||
from django.contrib.auth import logout
 | 
					from django.contrib.auth import logout
 | 
				
			||||||
from django.contrib.auth.mixins import LoginRequiredMixin
 | 
					from django.contrib.auth.mixins import LoginRequiredMixin
 | 
				
			||||||
@@ -263,6 +261,7 @@ class PictureUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin, Det
 | 
				
			|||||||
        return context
 | 
					        return context
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_success_url(self):
 | 
					    def get_success_url(self):
 | 
				
			||||||
 | 
					        """Redirect to profile page after upload"""
 | 
				
			||||||
        return reverse_lazy('member:user_detail', kwargs={'pk': self.object.id})
 | 
					        return reverse_lazy('member:user_detail', kwargs={'pk': self.object.id})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def post(self, request, *args, **kwargs):
 | 
					    def post(self, request, *args, **kwargs):
 | 
				
			||||||
@@ -271,26 +270,9 @@ class PictureUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin, Det
 | 
				
			|||||||
        return self.form_valid(form) if form.is_valid() else self.form_invalid(form)
 | 
					        return self.form_valid(form) if form.is_valid() else self.form_invalid(form)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def form_valid(self, form):
 | 
					    def form_valid(self, form):
 | 
				
			||||||
 | 
					        """Save image to note"""
 | 
				
			||||||
        image_field = form.cleaned_data['image']
 | 
					        image_field = form.cleaned_data['image']
 | 
				
			||||||
        x = form.cleaned_data['x']
 | 
					        image_field.name = "{}_pic.png".format(self.object.note.pk)
 | 
				
			||||||
        y = form.cleaned_data['y']
 | 
					 | 
				
			||||||
        w = form.cleaned_data['width']
 | 
					 | 
				
			||||||
        h = form.cleaned_data['height']
 | 
					 | 
				
			||||||
        # image crop and resize
 | 
					 | 
				
			||||||
        image_file = io.BytesIO(image_field.read())
 | 
					 | 
				
			||||||
        # ext = image_field.name.split('.')[-1].lower()
 | 
					 | 
				
			||||||
        # TODO: support GIF format
 | 
					 | 
				
			||||||
        image = Image.open(image_file)
 | 
					 | 
				
			||||||
        image = image.crop((x, y, x + w, y + h))
 | 
					 | 
				
			||||||
        image_clean = image.resize((settings.PIC_WIDTH,
 | 
					 | 
				
			||||||
                                    settings.PIC_RATIO * settings.PIC_WIDTH),
 | 
					 | 
				
			||||||
                                   Image.ANTIALIAS)
 | 
					 | 
				
			||||||
        image_file = io.BytesIO()
 | 
					 | 
				
			||||||
        image_clean.save(image_file, "PNG")
 | 
					 | 
				
			||||||
        image_field.file = image_file
 | 
					 | 
				
			||||||
        # renaming
 | 
					 | 
				
			||||||
        filename = "{}_pic.png".format(self.object.note.pk)
 | 
					 | 
				
			||||||
        image_field.name = filename
 | 
					 | 
				
			||||||
        self.object.note.display_image = image_field
 | 
					        self.object.note.display_image = image_field
 | 
				
			||||||
        self.object.note.save()
 | 
					        self.object.note.save()
 | 
				
			||||||
        return super().form_valid(form)
 | 
					        return super().form_valid(form)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user