django - 我在哪里可以清理表单集的数据?

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

我有一个视图函数,其中有两个表单,一个用于创建 post,另一个是用于保存图像的表单集。我在哪里可以清理表单集的数据?我想将图像调整为特定大小。我可以为类似于 class 的表单集创建 class 吗?

编辑: formset 正在保存,但图像未被清理。

@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

通常您会在与您的表单集相关联的 forms.py 中执行此操作。您可以覆盖 clean 方法并执行任何您想做的事情。