14

I am using the model with FileField to deal with file uploading. Now the files can be uploaded successfully. However, there is one more small improvement I want to make, which is to create folder for the user with the username.

Here is the code I've tried

class UserFiles(models.Model):
    user = models.OneToOneField(User)
    file = models.FileField(upload_to='files/users/user.username/%Y_%m_%d/')

this would give the folder of 'user.username' instead of 'John'(one example of username)

I have also tried other ways like files/users/%user.username/%Y_%m_%d/ ,but it would not give the folder with the user name. Not sure how the syntax should be or whether this is possible.

Can you give some suggestions on this? Thank you very much for your help and explanation.

Mona
  • 1,425
  • 6
  • 21
  • 31
  • http://stackoverflow.com/questions/1190697/django-filefield-with-upload-to-determined-at-runtime?rq=1 solution found in this link – Mona Jul 09 '13 at 05:38

1 Answers1

27

Instead of a string try passing a function:

def generate_filename(self, filename):
    url = "files/users/%s/%s" % (self.user.username, filename)
    return url

class UserFiles(models.Model):
    user = models.OneToOneField(User)
    file = models.FileField(upload_to=generate_filename)
Victor Castillo Torres
  • 10,581
  • 7
  • 40
  • 50
  • hi, thank you very much for your answer, the first solution works fine. The second one, the username of the user object,i.e. user.username can not be recognized. – Mona Jul 09 '13 at 05:45
  • try changging `str(user.username)` for `str(user)`, You're welcome! :D – Victor Castillo Torres Jul 09 '13 at 05:47
  • that would give as the name of the folder – Mona Jul 09 '13 at 05:59
  • Well that it's returning `OneToOneField` instance, so I think you have to choose the first option. – Victor Castillo Torres Jul 09 '13 at 06:06
  • It's a generally a Bad Idea to name functions using reserved words like `file` because you effectively overwrite the builtin function and introduce unpredictable behaviour. A better choice here might have been `generate_filename()`. – Daniel Quinn Mar 24 '15 at 10:51
  • and what do i pass from my views in .save call?? – DeadDjangoDjoker Jun 26 '15 at 02:26
  • 1
    @DeadDjangoDjoker You only have to save the object, the function gets executed before saving by its own :D – Victor Castillo Torres Jun 26 '15 at 03:06
  • where is generate_filename getting the self and filename arguments? and why doesn't it need () at the end in the kwargs? – ss7 Jul 16 '15 at 22:56
  • @shenk a bit late, but here is the answer: before saving the object, django executes the function you passed as an argument to the FielField like this generate_filename(userfiles_instance, name_of_the_original_file). Regarding the parenthesis, as you need more than 1 value to the string in order to format it you have to provide an iterable, and by using parenthesis you build a tuple which is an iterable – Victor Castillo Torres Jun 19 '17 at 17:07