1

Possible Duplicate:
Django FileField with upload_to determined at runtime

I am creating a web application that allows user to store files online, like Dropbox. A user's file is modeled by the model Item:

from django.db import models
from django.contrib.auth.models import User


class Item(models.Model):
    # Name of file
    name = models.CharField(max_length=200)

    # Site user who owns the file
    user = models.ForeignKey(User)

    # Path to file in database
    # Python complains here since "username" is an attribute of the User class, not
    # an attribute of ForeignKey.
    file = models.FileField(upload_to=(user.username + '/' + name))

Now if you look the upload_to argument to FileField, I want to specify where files are stored in my database. If I have a user "bill" with file "myfile" his file should go under the path "bill/myfile".

To get this string I tried "user.username + '/' + name" but python complains that user doesn't have an attribute username because user isn't a User object: it's a ForeignKey that stores a User. So the question is, how do I get the user object from the ForeignKey within code?

Now regarding Django's database API that won't work because the object has to be saved to the database before I can use the API. This is not the case as I need the data during construction of my Item object.

Community
  • 1
  • 1
user1299784
  • 2,019
  • 18
  • 30
  • 2
    Files aren't stored in your database. Their paths are stored in your database, but the files (typically) are stored in directories on disk, at your MEDIA_ROOT + the upload_to argument. – orokusaki Aug 21 '12 at 01:34

2 Answers2

1

With FileField you can put a [function on upload_to][1]

https://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.FileField.upload_to

Tarsis Azevedo
  • 1,463
  • 14
  • 21
1

Your approach is flawed either way because whatever you pass into upload_to is going to be called once. Even if user.username worked, you have to remember that it's only calculated when the class is defined.

You'll want to define a custom upload_to function to pass to the field.

def custom_upload_to(instance, filename):
     return '{instance.user.username}/'.format(instance=instance)

myfield = models.FileField(upload_to=custom_upload_to)
Yuji 'Tomita' Tomita
  • 115,817
  • 29
  • 282
  • 245