On 10/24/07, Thomas Guettler <[EMAIL PROTECTED]> wrote:
> I am one of the people who asked for this. I only want to use the
> primary key for a directory name. I think a filename is not enough:
> I don't want to store the files under MEDIA_ROOT. Otherwise you can't
> use access control, since the request gets served by apache/lighttpd, not
> django.

Well, whether it's stored under MEDIA_ROOT is unrelated to whether it
uses just a filename for each instance. The current filestorage patch
supports storing files anywhere on your filesystem (as long as you set
the proper permissions), not just under MEDIA_ROOT.

> Example: if an Object class should have N attachments:
>
> class Object(models.Model):
>     pass
>
> class Attachment(models.Model):
>     object=models.ForeignKey(Object)
>     filename=models.FileField()
>
> The file should be saved under /non-public-path/attachments/OBJECT_ID/

This is definitely a useful storage strategy. And, in fact, it
illustrates that a callback would indeed be the correct course of
action. A format string for this setup would require the use of
"object_id" explicitly, which most people shouldn't have to worry
about. And a format string would be completely incapable of following
relationships, so if you had a Category model as well, and wanted
/CATEGORY_ID/OBJECT_ID/, it just couldn't be done.

> For me, it's enough to store the basename in the database. The
> leading directory (/non-puglic-path/attachments) could be stored in the
> models.py file as keyword argument:
>
>     filename=models.FileField(media_root="/...")

With the filestorage patch as it stands right now, you'd actually do
something like this:

from django.db import models
from django.core.filestorage.filesystem import FileSystemBackend

storage = FileSystemBackend(location='/non-public-path/attachments')

class Object(models.Model):
    pass

class Attachment(models.Model):
    object=models.ForeignKey(Object)
    filename=models.FileField(backend=storage)

> The idea of Robert Coup to use a callback looks good.

The idea is growing on me, especially once I considered a convention
that would make it look really slick:

class Attachment(models.Model):
    object=models.ForeignKey(Object)

    def get_filename(self, filename):
        return '%s/%s' % (self.object.pk, filename)

    filename=models.FileField(backend=storage, filename=get_filename)

This way, get_filename() becomes a bound method on the model, and can
be used elsewhere, just to see what the filename would be for the
object, without retrieving it. Of course, this is just one convention
that a simple callback would enable, but I like it anyway.

One addition to the callback idea: As I show above, it should
definitely include a filename argument, which would be the original
filename. That way, in cases like yours, you can modify it with
details from the object, but still include the original filename.

> Nevertheless, using
> anything other than a primary key is most of the time nonsense, since
> attribute can change, but the physical filename does not (except you have a
> script which updates the filesystem).

I agree with you there, but people won't always assume this to be the case.

> Please announce it here, if you update your patches. I will try them.
> Or send a email to [EMAIL PROTECTED]

I'll definitely announce it here to get more feedback.

One last question, folks. I'm not a big fan of using the name
"filename" for the callback argument, because it might confuse people
into thinking that the callback will always be used to determine the
filename. Once it's stored, of course, the database value will be used
instead, and I think this should be made clear.

I think something like "get_filename" might work? Or perhaps even
"default"? The standard is to have the "default" callback not take any
arguments, but it might make more sense to at least reuse the name,
but with FileField calling it with the instance and filename as
arguments. Thoughts?

-Gul

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to