How do I detect if my user has uploaded an ImageField or FileField?

Question:

I have the following model and function to set the upload paths for either image files or other files (which will be audio files).

def upload_to(instance, filename):
    # Check for image or sound file and put in appropriate directory
    if isinstance(instance, models.ImageField):
        print("detected image file")
        return "x/img/%s" % (filename)
    else:
        print("detected non-image file")
        return "x/aud/%s" % (filename)

class Tile(models.Model):
    image = models.ImageField(upload_to=upload_to, default="../static/x/img/default.svg")
    sound = models.FileField(upload_to=upload_to, null=True, blank=True)

The condition in upload_to is not correct, I realize, as instance is an instance of the tile object with all fields, but I’m not sure what to do in the upload_to function to find out if the file that was just uploaded by the user is an ImageField or FileField.

Asked By: ragmats

||

Answers:

Could you have two separate upload_to functions, one for each field/file type?

def upload_to_image(instance, filename):
    return "x/img/%s" % (filename)

def upload_to_sound(instance, filename):
    return "x/aud/%s" % (filename)

class Tile(models.Model):
    image = models.ImageField(upload_to=upload_to_image, default="../static/x/img/default.svg")
    sound = models.FileField(upload_to=upload_to_sound, null=True, blank=True)

In fact, if you just need separate directories for each field type, it looks like you should be able to pass that directly to the upload_to field:

class Tile(models.Model):
    image = models.ImageField(upload_to="x/img/", default="../static/x/img/default.svg")
    sound = models.FileField(upload_to="x/aud/", null=True, blank=True)

and omit the callback functions entirely.

Answered By: Warren Henning