复制 Django 表单 request.FILES 以使用智能字段上传多个图像文件

Replicating Django forms request.FILES to upload multiple image files using smartfields

我正在尝试使用 Django 表单拍摄单张图像,然后将其上传到 3 headers 以下的调整大小版本。我什至可以用 request.POST QueryDict 做到这一点,但不能用 request.FILES MultiValueDict 即使它显示了各个字段名称的填充数据。

我的Views.py

def image_add(request,article_id):
    template_name = 'blogs/image_add.html'
    articles = Article.objects.get(article_id=article_id)
    form = ImageAddForm
    if request.method == 'POST':
        image = request.FILES["image_1080"]
        request.FILES['image_800'] = image
        request.FILES['image_350'] = image
        print(request.POST)
        print(request.FILES)
        form = ImageAddForm(request.POST, request.FILES)
        if form.is_valid():
            new_form = form.save(commit=False)
            new_form.dir_id = article_id
            new_form.save()
            return redirect('/')
    context = {'form':form,'articles':articles}
    return render(request, template_name,context)

我的Models.py

from smartfields import fields
from smartfields.dependencies import FileDependency
from smartfields.processors import ImageProcessor

    class Images(models.Model):
        dir_id = models.CharField(max_length=10,null=True)
        image_1080 = fields.ImageField(upload_to=img_1080_dir_path, name="image_1080", dependencies=[
            FileDependency(processor=ImageProcessor(
                format='PNG', scale={'max_width': 1080, 'max_height': 1080}))
        ])
        image_800 = fields.ImageField(upload_to=img_800_dir_path, blank=True, name="image_800", dependencies=[
            FileDependency(processor=ImageProcessor(
                format='PNG', scale={'max_width': 800, 'max_height': 800}))
        ])
        image_350 = fields.ImageField(upload_to=img_350_dir_path, blank=True, name="image_350", dependencies=[
            FileDependency(processor=ImageProcessor(
                format='PNG', scale={'max_width': 350, 'max_height': 350}))
        ])

我的Forms.py

class ImageAddForm(forms.ModelForm):
    class Meta:
        model = Images
        fields = ('name','alt_text','image_1080')
        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control'}),
            'alt_text': forms.TextInput(attrs={'class': 'form-control'}),
            'image_1080': forms.ClearableFileInput(attrs={'class': 'form-file-input'})
            }

这只会保存一张图片 - 'image_1080' 但不会保存另外两张图片。

您覆盖 POST 参数的方法更像是一种 hack,因为从概念上讲,这意味着您忽略了假定来自用户的数据。所以这是我一般建议反对的事情:

    if request.method == 'POST':
        image = request.FILES["image_1080"]
        request.FILES['image_800'] = image
        request.FILES['image_350'] = image

我怀疑这种方法行不通,因为文件的同一实例在许多字段之间共享。相反,正确的方法是简单地使用一个表单字段作为输入,然后让智能字段为您将其他字段附加到模型。另外,我建议保留上传的原始文件,以防您将来需要再次调整大小和更改格式:

from smartfields import utils

class Images(models.Model):
    image = fields.ImageField(
        upload_to=utils.UploadTo(generator=True, field_name='image'),
        dependencies=[
            FileDependency(suffix='1080', processor=ImageProcessor(
                format='PNG', scale={'max_width': 1080, 'max_height': 1080}),
            FileDependency(suffix='800', processor=ImageProcessor(
                format='PNG', scale={'max_width': 800, 'max_height': 800}),
            FileDependency(suffix='350', processor=ImageProcessor(
                format='PNG', scale={'max_width': 350, 'max_height': 350}))
        ])

上传图片到image字段时,smartfields会自动为你的Images模型添加额外的字段,例如:

> i = Images(my_image)
> i.save()
> print(i.image)      # original
> print(i.image_1080) # resized to 1080
> print(i.image_800)