首页 > 解决方案 > 如何使用 Django Rest Framework 支持可选或空 FileField?

问题描述

我在现有模型中添加了一个新的 FileField“照片”并迁移了数据库。当我尝试使用 DRF 返回数据时,我收到错误消息“ValueError:'photo' 属性没有与之关联的文件。” 照片列包含空值。

该字段应该是可选的。

模型.py:

def photo_directory_path(instance, filename):
    return 'photos/{0}/{1}'.format(instance.id, filename)

class MyModel(models.Model):
...
    photo = models.FileField(blank = True, editable = True, upload_to=photo_directory_path)
...

class MyModel_l10n(models.Model):
...
    mymodel = models.ForeignKey(MyModel, on_delete=models.CASCADE, related_name='%(class)s_mymodel')    
...

序列化程序.py:

class MyModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = MyModel
        fields = ['photo']

class MyModel_l10nSerializer(serializers.ModelSerializer):
    photo = serializers.ReadOnlyField(source='mymodel.photo', required = False, allow_null = True)

    class Meta:
        model = MyModel_l10n
        fields = ['photo', ...]

视图.py:

    res = MyModel_l10n.objects.filter(...)
    serializer = MyModel_l10nSerializer(res, many=True)
    return Response (serializer.data)

错误信息:

ValueError: The 'photo' attribute has no file associated with it.

编辑:问题仍然存在我设置字段 null = True 并使列为空。此外,包括 required = False 到 serializers.ReadOnlyField 也没有帮助。

该问题仅发生在 MyModel_l10n 上。如果我序列化 MyModel,则丢失的文件不是问题。

标签: djangodjango-modelsdjango-rest-framework

解决方案


当 photo 字段不为空,但文件系统上没有基础文件时,会引发您看到的错误。我认为这可能与您使用blank=True定义文件字段的方式有关。这样做后,您的模型实例将在文件字段上保存为空值(非 null),并在尝试获取与该字段关联的实际文件时引发异常。

您可以尝试像这样定义您的字段:

class MyModel(models.Model):
    ...
    photo = models.FileField(null = True, editable = True, upload_to=photo_directory_path)    
    ...

推荐阅读