在保存到磁盘之前如何验证ImageField?

时间:2019-03-21 16:52:34

标签: django

我正在尝试将图像从某些外部URL放入ImageField。

这是我的模特:

class MyModel(models.Model):
    id = models.AutoField(primary_key=True)
    photo = models.ImageField(
        upload_to=_upload_path,
        validators=[...]
    )

这就是我从url接收文件的方式:

from io import BytesIO
import requests
from django.core.files import File

fp = BytesIO()
fp.write(requests.get(url).content)
file = File(fp)

现在,如果需要,我需要将此文件附加到MyModel:

mymodel = MyModel()
mymodel.photo.save("some_filename.jpg", file)

我可以看到文件已保存到upload_path/some_filename.jpg 没有任何验证(MyModel.photo字段的所有验证器都被忽略了)

是否可以做类似的事情:

mymodel.photo = ???
mymodel.full_clean()
mymodel.save()

如此some_filename.jpg仅在进行必要的验证后才出现在磁盘上吗?我只需要通过ImageField验证器验证文件,然后将其保存到磁盘即可。

2 个答案:

答案 0 :(得分:0)

不是个好主意,将图像保存到 DB 中,存在于 media 文件夹中的目的,但也许您可以使用此 BinaryField BinaryField

models.py

class ExampleModel(model.Model):
    image = models.BinaryField(blank=True)

views.py

def uploadImageIntoDb(request):
    image_file = request.FILES['image'].file.read()
    ExampleModel.objects.create(image=image_file)

答案 1 :(得分:0)

根据文档https://docs.djangoproject.com/en/2.1/ref/validators/

  

请注意,当您保存模型时,验证程序不会自动运行,但是,如果您使用的是ModelForm,它将在表单中包含的任何字段上运行验证程序。

因此,需要一个ModelForm来通过验证器来验证模型:

# receiving InMemoryUploadedFile from url (pseudocode)
response = requests.get(url)
fp = io.BytesIO()
fp.write(response.content)
fp.seek(0)
file = django.core.files.File(fp)
in_memory_uploaded_file = django.core.files.uploadedfile.InMemoryUploadedFile(
    fp, 'field_name', 'file_name.jpg', mime_type, file_size, None
)

# form validation
form_data = {}
form_files = {
    photo: in_memory_uploaded_file
}
mymodel_form = ModelForm(data=form_data, files=form_files) 
if mymodel_form.is_valid():
    mymodel = mymodel_form.save(commit=False)
    mymodel.save()

def get_image_from_url(self, url: str):
    parsed_url = urlparse(url)
    filename = os.path.basename(parsed_url.path)
    response = requests.get(url)