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 -~----------~----~----~----~------~----~------~--~---