Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django instance.id=None when uploading image

instance.id is returning None when upload images through the admin page. The idea was to upload all the images of each Residence to a different folder. Here's my code:

models.py

from django.db import models
import os

def get_image_path(instance, filename):
    return os.path.join('photos', "residence_%s" % instance.id, filename)


# Create your models here.
class Residence(models.Model):
    big_image = models.ImageField("Main Image",upload_to=get_image_path)
    small_images = models.ImageField("Small Images",upload_to=get_image_path, blank=True, null=True)

settings.py

MEDIA_URL = '/media/'

EDIT: It works if I modify the image after the model is already added.


2 Answers

You can't do it in that way unless you implement your custom dynamic file upload field. Because you try to access instance.id, but instance isn't saved yet and doesn't have an id.

Here you are some resources that will help you achieve what you want:

  • dynamic file upload path with current instance id
  • Django admin file upload with current model id
like image 118
wencakisa Avatar answered Apr 30 '26 00:04

wencakisa


Another nice way to solve this problem that requires much less code is to have your model use a UUID for the primary key rather then the database generated id. This means at the point the model is saved for the first time the UUID is already known and can be used with any upload_to callbacks.

So for the original example you would do something like this

from django.db import models

import uuid
import os

def get_image_path(instance, filename):
    return os.path.join('photos', "residence_%s" % str(instance.id), filename)

# Create your models here.
class Residence(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    big_image = models.ImageField("Main Image",upload_to=get_image_path)
    small_images = models.ImageField("Small Images",upload_to=get_image_path, blank=True, null=True)

See Django's UUIDField reference for more info

like image 28
TimmyGee Avatar answered Apr 30 '26 00:04

TimmyGee



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!