7

I'm using django-filer for the first time, and it looks great, and work pretty well.

But all my images are being uploaded to the 'Unsorted Uploads' folder, and I can't figure out a way to put them in a specific one. This strikes me as a fundamental feature, and given that it allows you create folders, this must be possible, right? But I can't find it in the docs, and a quick look through the source didn't help me.

I have a basic setup like:

class Story(models.Model):
    image = FilerImageField()

class Gift(models.Model):
    # some stuff

class GiftImage(models.Model):
    gift = models.ForeignKey(Gift)
    image = FilerImageField()

And I want GiftImage.image and Story.image to go into separate folders, so as to make sorting/searching easier for the admin user.

I have tried

image = FilerImageField(upload_to='somewhere') # How a django ImageField would do it
image = FilerImageField(folder='somewhere') # a guess
image = FilerImageField(name='somewhere') # a guess
image = FilerImageField(folder_name='somewhere') # another guess

All of these either give me a "TypeError: init() got an unexpected keyword argument ..." or just don't do what I was hoping.

Cheers!

David Downes
  • 1,145
  • 10
  • 24
  • Did you ever figure this out? I'm in the same boat now. It seems like such an obvious and basic need, I can't believe there isn't a way to do it. – Chris Feb 23 '18 at 23:36
  • Sorry, it's been a while since I worked on that project, but I don't think I ever figured it out :( – David Downes Mar 05 '18 at 17:43
  • Thanks, I appreciate the response. I found a sort of halfway workaround, I'll put an answer here in case someone else stumbles across this. – Chris Mar 13 '18 at 16:39
  • @DavidDownes how to use this library docs are not clear , any resource – Atif Shafi Oct 04 '21 at 10:43

2 Answers2

2

In case anyone else comes across this, here is what I found for a workaround. If you give the field a default value, then the upload will default to whatever folder that default image is in. In my particular case, I wanted a default image anyways so this killed two birds with one stone.

Here is how you can do that:

First, note that FilerImageField is really a foreign key to filer.Image. So, to add a default, you need to first add a filer.Image to your database to use as the default, putting it in the folder you want uploads to go to. How you do that is up to you -- via your admin, or a data migration somehow, perhaps. Then you can make that image the default using a method, like this:

def get_default_image():
    from filer.models.imagemodels import Image
    try:
        return Image.objects.filter(name='My Default Image').order_by('-uploaded_at')[0]
    except IndexError:
        return None

class MyModel(models.Model):
    image = FilerImageField(null=True, blank=True, default=get_default_image)

This implementation has some obvious caveats. If your default image name changes you are going to be back to having no default image (and, thus, uploading to 'Unsorted Uploads'). And if there are multiple with that name, your method has to choose one. I choose the most recently uploaded one.

If you are confident you'll never want to change the default image instance you could just select it by id.

So this is a bit kludgy but if you are scrambling to get something working maybe you are ok with that. Hope this helps someone.

Chris
  • 366
  • 3
  • 11
0

Not possible in a nice and supported way AFAICT.

I'm using a workaround relies on JS to change the URL.

templates/admin/<your_app>/<your_model>/change_form.html

{% extends "admin/change_form.html" %}

{% block extrahead %}
    {{ block.super }}
    <script>
        window.addEventListener('load', function() {
            const wrapper = document.querySelector('.js-filer-dropzone');
            const dropzone = wrapper.dropzone;
            const button = wrapper.querySelector('.js-related-lookup');
            button.href = button.href.replace('/last/', '/1/list/');
            dropzone.options.url = dropzone.options.url.replace('/no_folder/', '/1/');
        });
    </script>
{% endblock extrahead %}

1 is the ID of the target folder. Problem is, of course, that folders can get deleted and even if recreated with exactly the same name they will have a different ID.

Some more tweaking would be needed if there are multiple fields on the page, and/or if they are part of an inline. YMMV.


Another way would be to override filer/templates/admin/filer/widgets/admin_file.html and change

{% url 'admin:filer-ajax_upload' %}

to

{% url 'admin:filer-ajax_upload' folder_id=1 %}
frnhr
  • 12,354
  • 9
  • 63
  • 90