Opened 2 years ago

Last modified 14 months ago

#25756 new Bug

ArrayField does not work with FileField

Reported by: Anthony Dong Owned by:
Component: contrib.postgres Version: 1.8
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When using the following models.py definition :

from django.contrib.postgres.fields import ArrayField

class Album(models.Model):
    pictures = ArrayField(models.FileField(upload_to='files'))

And the following admin.py

from django.contrib.postgres.forms import SplitArrayField
class AlbumForm(forms.ModelForm):
    pictures = SplitArrayField(forms.FileField(), size=2)
    class Meta:
        model = models.Album
        fields = '__all__'

class AlbumAdmin(admin.ModelAdmin):
    form = AlbumForm

admin.site.register(models.Album, AlbumAdmin)

Creating a new Album in the Django admin works, but:

  • Files are not getting saved
  • Retrieving a FieldFile is impossible:
    python manage.py shell
    from my_app.models import Album
    Album.objects.get().pictures == [u'filename.png', u'filename2.png']
    

I would have expected a list of FieldFiles.

Attachments (1)

multiple.py (4.5 KB) - added by Riccardo Di Virgilio 2 years ago.

Download all attachments as: .zip

Change History (4)

comment:1 Changed 2 years ago by Tim Graham

Triage Stage: UnreviewedAccepted

I'm not sure to what extent we can fix this, but if not, we can document the limitation or try to add a helpful error message indicating that it's unsupported.

comment:2 Changed 2 years ago by Riccardo Di Virgilio

Hi, I need to implement an array field for multiple files, and currently this is not supported.

after hours of debugging I found out several design problems that are preventing to have a clean implementation of this field.

  1. If you use a FileField this field is using a descriptor to transform strings into File objects (instead of to_python), which is why the array field is always returning strings and not file objects.
  1. The save method of FileField is setting the instance file attribute to a file, which in this case is wrong because it should be a list of files.
  1. the pre save method in file field is the one that is actually saving the file, since ArrayField is not calling the super of that, this cannot work.

array field should support file field out of the box (and this involves also creating a multi file input widget that can work also in the admin).

another solution is to have a special ArrayFileField, which can also return an ArrayFile object that is iterable (instead of a list).

I can attach a "working" and dirty version of it.

Last edited 2 years ago by Riccardo Di Virgilio (previous) (diff)

Changed 2 years ago by Riccardo Di Virgilio

Attachment: multiple.py added

comment:3 Changed 14 months ago by Nikolai Ryzhkov

Hi. I've faced this limitation.

After quick review of FileField and ArrayField I found out that this problem can't be resolved without redesign of ArrayField.
We can't append a FileField's instance to list which is a instance of ArrayField. The FileField's instance requires access to field (It should get upload_to and storage). So we should have wrapper under list which will be know his field first.

Note: See TracTickets for help on using tickets.
Back to Top