Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用djangorestframework更新ImageField/FileField?_Django_Django Rest Framework_Filefield - Fatal编程技术网

如何使用djangorestframework更新ImageField/FileField?

如何使用djangorestframework更新ImageField/FileField?,django,django-rest-framework,filefield,Django,Django Rest Framework,Filefield,我想使用djangorestframework更新模型。我不需要更新所有字段,所以我使用补丁。然而,在我的表单中,我还有一个图像字段(称为“logo”),这是我的模型所必需的。当我尝试“修补”对象,但没有为该字段选择新图像时,drf会抛出一个错误(“徽标”:“此字段是必需的”) 我知道在使用django表单时,文件字段会得到特殊处理,这意味着如果它们已经有值,则提交带有空文件字段的表单时只会保留旧值。使用djangorestframework序列化程序有什么方法可以做到这一点吗 一些代码可以更好

我想使用djangorestframework更新模型。我不需要更新所有字段,所以我使用补丁。然而,在我的表单中,我还有一个图像字段(称为“logo”),这是我的模型所必需的。当我尝试“修补”对象,但没有为该字段选择新图像时,drf会抛出一个错误(“徽标”:“此字段是必需的”)

我知道在使用django表单时,文件字段会得到特殊处理,这意味着如果它们已经有值,则提交带有空文件字段的表单时只会保留旧值。使用djangorestframework序列化程序有什么方法可以做到这一点吗

一些代码可以更好地理解:

# models.py
class Brand(models.Model):
    name = models.CharField(_('name'), max_length=250)
    logo = models.ImageField(upload_to='brands/')

# serializers.py
class BrandSerializer(serializers.ModelSerializer):

    class Meta:
        model = Brand
        fields = (
            'id',
            'name',
            'logo',
        )

# detail.html
<form method="post" enctype="multipart/form-data">
    {%csrf_token%}

        <input name="name" type="text" maxlength="30" value="{{ brand.name }}"/>
        <input name="logo" type="file" accept="image/*"/>

    <input name="_method" type="hidden" value="PATCH">
    <input type="submit" value="Update"/>

</form>  
#models.py
类别品牌(型号.型号):
name=models.CharField(u('name'),最大长度=250)
logo=models.ImageField(上传到class='brands/')
#序列化程序.py
类BrandSerializer(serializers.ModelSerializer):
类元:
型号=品牌
字段=(
“id”,
“姓名”,
"标志",,
)
#detail.html
{%csrf_令牌%}
目前我能想到的最好办法是在调用序列化程序之前,从我的
请求.DATA
中删除
logo
条目。我很好奇是否有人知道更好的解决办法。谢谢。

尝试一下,希望你能得到解决方案。 或者看看这个cade,完全希望它能为你工作

class ImageSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Brand
        fields = ('name', 'logo')
    def saveImage(self, imgFileUri):
        #parse dataUri and save locally, return local path
        return 'somewhereOverTheBlah'

    def restore_fields(self, data, files):

        reverted_data = {}

        if data is not None and not isinstance(data, dict):
            self._errors['non_field_errors'] = ['Invalid data']
            return None

        for field_name, field in self.fields.items():
            """
            So it  is iterating over the fields to serialize, when we find the file field
            do something different (in this case look for the fileUri field, handle it and replace
            it inside of the reverted_data dictionary with the intended file field
            """

            if(field_name == 'file'):
                field_name = 'dataUri'
                field = fields.CharField()
                try:
                    # restore using the built in mechanism
                    field.field_from_native(data, files, field_name, reverted_data)
                    # take the dataUri, save it to disk and return the Path
                    value = reverted_data[field_name]
                    path = self.saveImage(value)
                    # set the file <Path> property on the model, remove the old dataUri
                    reverted_data['file'] = path
                    del reverted_data[field_name]

                except ValidationError as err:
                    self._errors[field_name] = list(err.messages)
            else:
                field.initialize(parent=self, field_name=field_name)
                try:
                    field.field_from_native(data, files, field_name, reverted_data)
                except ValidationError as err:
                    self._errors[field_name] = list(err.messages)

        return reverted_data
类ImageSerializer(serializers.HyperlinkedModelSerializer):
类元:
型号=品牌
字段=(“名称”、“徽标”)
def saveImage(self,imgFileUri):
#解析dataUri并本地保存,返回本地路径
返回“somewhere theblah”
def restore_字段(自身、数据、文件):
还原的_数据={}
如果数据不是无且不存在(数据,dict):
self._errors['non_field_errors']=['Invalid data']
一无所获
对于字段名称,self.fields.items()中的字段:
"""
因此,当我们找到文件字段时,它将遍历字段进行序列化
做一些不同的事情(在本例中,查找fileUri字段,处理它并替换它)
它位于还原的_数据字典内,并带有指定的文件字段
"""
如果(字段_name=='file'):
字段名称='dataUri'
field=fields.CharField()
尝试:
#使用内置机制进行恢复
field.field_from_native(数据、文件、字段名称、还原的_数据)
#获取dataUri,将其保存到磁盘并返回路径
值=还原的\u数据[字段\u名称]
path=self.saveImage(值)
#设置模型的file属性,删除旧的dataUri
还原的_数据['file']=路径
删除还原的\u数据[字段\u名称]
除ValidationError作为错误外:
self.\u errors[字段\u name]=列表(错误消息)
其他:
初始化(父项=自身,字段名称=字段名称)
尝试:
field.field_from_native(数据、文件、字段名称、还原的_数据)
除ValidationError作为错误外:
self.\u errors[字段\u name]=列表(错误消息)
返回还原的_数据