tputkonen
tputkonen

Reputation: 5729

How to support optional or empty FileField with Django Rest Framework?

I added a new FileField 'photo' to my existing model and migrated the database. When I try to return data using DRF, I get the error message "ValueError: The 'photo' attribute has no file associated with it." Photo column contains empty values.

The field should be optional.

models.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')    
...

serializers.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', ...]

views.py:

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

error message:

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

EDIT: problem persists also I set the fields null = True and make the column null. Also, including required = False to serializers.ReadOnlyField didn't help.

The problem only happens with MyModel_l10n. If I serialize MyModel, the missing file is not on issue.

Upvotes: 0

Views: 4647

Answers (2)

tputkonen
tputkonen

Reputation: 5729

Changing the ReadOnlyField to FileField with required = False, allow_null=True did the trick.

Upvotes: 1

Ozgur Akcali
Ozgur Akcali

Reputation: 5492

The error you see is raised when the photo field is not null, but has no underlying file on the file system. I think it might be related to the way you define the file field with blank=True. When done so, your model instances are saved with an empty value (not null) on the file field, and raises the exception when trying to get the actual file assicicated with that field.

You can try instead defining your field like this:

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

Upvotes: 0

Related Questions