pythondjangodjango-modelsdjango-file-upload

Use value of primary key in FileField upload_to function


Given the following model I am attempting to use the models ID field (a UUID) in the upload_to path but its defined as None, presumably as it hasn't been generated at that point.

If I use a UUID field that isn't defined as the primary key it works OK.

How do I get the value of the id field at the point picture_path is ran?

# models.py
    
class Foo(models.Model)
    
  def picture_path(instance, filename):  
    return 'pictures/{0}/{1}'.format(instance.id, filename)
    
  id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
  picture = models.ImageField(upload_to=picture_path, null=True, blank=True)

(I know that django will automagically append random chars to avoid duplicate file names, this is a deliberately simplified example, in the real app need to keep each models files in a seperate folder)


Solution

  • Since in your example primary key is generated as uuid4 and does not depend on DB counter - you can safely generate it upfront.

    In other words - you don't have to wait for DB insert to get primary key - you can make it yourself and then insert into DB (being pretty sure that it's unique - because it's uuid4)

    So, in code the fix will be:

    def picture_path(instance, filename):
        instance.id = str(uuid.uuid4())
        return 'pictures/{0}/{1}'.format(instance.id, filename)
    

    Call to picture_path is done before save. And when in save id is populated from outside - it won't be overwritten by Django.