Mint
Mint

Reputation: 1059

django - where can i clean the data of a formset?

I have a view function where I have two forms, one to create a post and the other is a formset to save images. Where can I clean the data of the formset? I want to resize the images to a particular size. Can i create a class for the formset similar to a class?

Edit: formset is saving but the image is not being cleaned.

@login_required(login_url='/accounts/login/')
def postCreateView(request):
  ImageFormset = modelformset_factory(Image, fields=('image',), extra=3)
  if request.method == 'POST':
    form = PostCreateForm(request.POST)
    formset = ImageFormset(request.POST or None, request.FILES or None)
    if form.is_valid() and formset.is_valid():
      post = form.save(commit=False)
      post.user = request.user
      post.save()

      i = 1
      for instance in formset:
        try:
         photo = Image(post=post, 
                       image=instance.cleaned_data['image'], 
                       title=str(i))
          photo.save()
        except Exception as e:
          break
        return redirect('posts:post_list')
    else:
      form = PostCreateForm()
      formset = ImageFormset(queryset=Image.objects.none())
      context = {
              'form': form,
              'formset': formset,
      }
      return render(request, 'posts/post_form.html', context)

forms.py

class ImageForm(forms.ModelForm):
    image = forms.ImageField(required=False)

    class Meta:
        model = Image
        fields = ('image',)

    def clean_image(self, *args, **kwargs):
        from PIL import Image
        from io import BytesIO
        from django.core.files.uploadedfile import InMemoryUploadedFile
        from sys import getsizeof

        image = form.cleaned_data("image")
        if not image:
            image = None
            return image

        size = (140,140)

        im = Image.open(image)
        output = BytesIO()
        im.thumbnail(size)
        try:
            im.save(output, format='JPEG', quality=100)
            output.seek(0)
            image = InMemoryUploadedFile(output,'ImageField', "%s.jpg" %image.name.split('.')[0], 'image/jpeg', getsizeof(output), None)
        except:
            im.save(output, format='PNG', quality=100)
            output.seek(0)
            image = InMemoryUploadedFile(output,'ImageField', "%s.png" %image.name.split('.')[0], 'image/png', getsizeof(output), None)

        return image

Upvotes: 1

Views: 1539

Answers (1)

Oh Great One
Oh Great One

Reputation: 384

Usually you will do it in a forms.py that is associated with your formset. You can override the clean method and do whatever you would like.

Upvotes: 1

Related Questions