Django REST Framework文件上传不起作用

时间:2019-03-06 14:00:45

标签: django python-3.x django-rest-framework

在Django REST Framework文件上传中,

我有一个Model,它具有几个字段以及一个FileField,它是一个可选的附件。

class Task(model.Model):
    attachment = models.FileField(upload_to=default_location, null=True, blank=True)
    ... some extra fields

此模型有一个ModelViewset来实现CRUD功能。 用户可以在带有/不带有附件的模型中创建条目。

class TaskViewSet(viewsets.ModelViewSet):
    serializer_class = TaskSerializer

    def get_queryset(self):
        return Task.objects.all()

Serilaizer有一个额外的BooleanField来决定是否保留最后一个附件。该字段将在前端显示为复选框。

class TaskSerializer(serializers.ModelSerializer):
    keep_previous_attachment = serializers.BooleanField(default=False)

    class Meta: 
        model = Task
        fields = ['id','attachment', 'heading']

用户创建新条目时,它将按预期工作。它将附件存储到其默认位置。 当用户更新带有/不带有附件的条目时,事情将无法按预期进行。

当我使用PUT方法更新ModelViewset的URL时, 1.重新启动django服务器时,第一次尝试可以正常进行。先前的附件被覆盖。 2.对该URL的所有后续请求均无效。它只是重命名旧文件,重命名的文件成为当前附件。 3.如果使用PATCH方法,则根本无法访问序列化程序类的validated_data中的keep_previous_attachment。 4.调用instance.save之前,一切都按预期进行。该方法以某种方式引用了旧附件,重命名为其他附件,并将重命名的附件存储为当前附件,而旧附件仍保留在上载文件夹中。

预期结果是: 当用户使用更新视图更新现有条目时, 前一个附件应被覆盖,即删除前一个文件并存储新文件。

我已经覆盖了序列化器类的更新方法,其代码如下。我已经复制粘贴了序列化程序类的原始更新代码,并进行了一些更改。我无法达到预期的结果,因为instance.save方法没有覆盖先前的附件,即即使正在处理新的附件直到调用point instance.save方法,它仍在存储先前的附件。我尝试通过,force_update = True,它也不起作用。我无法解决这里的问题。

def update(self, instance, validated_data):

    from rest_framework.serializers import raise_errors_on_nested_writes
    raise_errors_on_nested_writes('update', self, validated_data)

    from rest_framework.utils import model_meta
    info = model_meta.get_field_info(instance)

    keep_old = validated_data.pop("keep_previous_attachment")
    validated_attachment = validated_data.pop("attachment")

    # Simply set each attribute on the instance, and then save it.
    # Note that unlike `.create()` we don't need to treat many-to-many
    # relationships as being a special case. During updates we already
    # have an instance pk for the relationships to be associated with.

    for attr, value in validated_data.items():
        if attr in info.relations and info.relations[attr].to_many:
            field = getattr(instance, attr)
            field.set(value)
        else:
            setattr(instance, attr, value)

    if keep_old is False:

        # delete the references to the older attachment
        instance.attachment = None 
        instance.save()


        deletion_path = os.path.join("location_of_folder")

        deleted = delete_task_attachments(deletion_path, request)

        instance.attachment = validated_attachment

    # if keep_old is True:
    #     instance.attachment is untouched by the code, so no update will happen.

    # print()
    # print("BEFORE SAVE")
    # print("instance.attachment")
    # print(instance.attachment)
    # print()

    instance.save()

    # print()
    # print("After SAVE")
    # print("instance.attachment")
    # print(instance.attachment)
    # print()

    return instance

请引导我解决。 预先感谢。

0 个答案:

没有答案