【问题标题】:How to update ImageField/ FileField using djangorestframework?如何使用 djangorestframework 更新 ImageField/ FileField?
【发布时间】:2014-08-28 09:58:54
【问题描述】:

我想使用 djangorestframework 更新模型。我不需要更新所有字段,所以我使用 PATCH。但是,在我的表单中,我还有一个图像字段(称为“徽标”),这是我的模型所必需的。当我尝试“修补”对象并且我没有为该字段选择新图像时,drf 会引发错误('logo': 'This field is required')。

我知道在使用 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>  

我现在能想到的最好的办法是在调用序列化程序之前从我的request.DATA 中删除logo 条目。我很好奇是否有人知道更好的解决方案。谢谢。

【问题讨论】:

    标签: django django-rest-framework filefield


    【解决方案1】:

    试试Link,希望你能得到解决方案。 或者看看这个 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
    

    【讨论】:

      猜你喜欢
      • 2011-02-10
      • 1970-01-01
      • 2012-05-08
      • 1970-01-01
      • 2020-11-27
      • 1970-01-01
      • 2013-04-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多