0

I would like to configure the mezzanine fork of django-filebrowser to create a subfolder when uploading an image, based on the title of a particular post within my mezzanine app.

The file field of that model requires setting "upload_to=", but I don't understand how I can make it point to a field value of its parent/foreignKey instance, rather than just a static value. I have tried defining a callable which points to exhibPost.title, as well as using it directly in the field as shown below.

I'd love to hear an explanation, I'm sure I'm misunderstanding something quite major about django here... Thanks

models.py - (imports omitted)
    class exhibPost(Displayable, RichText,):
        """
        An exhib post.
        """
        def __unicode__(self):
            return u'%s' % (self.id)

        showstart = models.DateField("Show Starts")
        showend = models.DateField("Show Ends")
        start_time = models.TimeField(null=True, blank=True)
        end_time = models.TimeField(null=True, blank=True)
        summary = models.CharField(max_length=200,null=True,default=get_val)

        class Meta:
            verbose_name = _("exhib post")
            verbose_name_plural = _("exhib posts")
            ordering = ("-publish_date",)

    class exhibImage(Orderable):
        '''
        An image for an exhib
        '''
        exhibPostKey = models.ForeignKey(exhibPost, related_name="images")


        file = FileField(_("File"), max_length=200, format="Image",
            upload_to=upload_to(
                "theme.exhibImage.file",
---->            exhibPost.title
            )
        )



        class Meta:
            verbose_name = _("Image")
            verbose_name_plural = _("Images")

EDIT

@Anzel

The function I'm referring to is defined in my models as

def get_upload_path(instance, filename):
    return os.path.join(
      "user_%d" % instance.owner.id, "car_%s" % instance.slug, filename)

...and I call it in the same place that I arrowed originally.

dnv
  • 969
  • 1
  • 7
  • 15
  • normally when you save a file, it will be saved in a static or dynamic path based on your *settings* or *Y/M/D* on creation. It's just a file path pointer in database. Do you want to rename your **Image filename** here? Or what do you want to achieve? – Anzel Oct 20 '14 at 22:20
  • The media library will by default store all uploaded images in one directory related to the content type, but I would like to further organise the images into folders by post(/instance?). I want to set the path basically, but through the proper methods so that its reflected in the admin interface. – dnv Oct 21 '14 at 00:27
  • --but also just generally, I would like to know how to link the value of one field to another, if that's possible ... – dnv Oct 21 '14 at 00:40
  • You can set **upload_to** with a dynamic *path* based on your instance. People just normally place uploaded files by Y/M/D format. But to get the actual `id` of your instance, your model has to be saved beforehand (the **instance** isn't created by the time file is uploaded, for example) – Anzel Oct 21 '14 at 08:25
  • you may refer to this [SO question](http://stackoverflow.com/questions/5135556/dynamic-file-path-in-django) to learn more. Just remember what I said above, ensuring the object is created beforehand. – Anzel Oct 21 '14 at 08:31
  • Hmm when I try this method, I get "get_upload_path() missing 2 required positional arguments: 'instance' and 'filename'". I did a quick google and [this link](https://github.com/stephenmcd/filebrowser-safe/issues/30) suggests that using callables as described might not work. Frustrating... – dnv Oct 21 '14 at 23:59
  • Oh, `get_upload_path()` is only an example how you could achieve what you want. But yes, like the link you provided with similar meaning, IF the model is not saved beforehand, it won't work. – Anzel Oct 22 '14 at 00:04
  • Problem is, my admin menu has an entry saved, and it works until I alter the model to refer to the callable, at which point I get a positional argument error. – dnv Oct 22 '14 at 00:06
  • Another fail case would be, user uploads an image in **admin** before creating that `exhibPost` – Anzel Oct 22 '14 at 00:08
  • Doesn't positional argument error imply that the two parameters arent being passed as opposed to a database mismatch? – dnv Oct 22 '14 at 00:11
  • I think the best common approach is let user create and manage their only *Media/Tree/Folder*, it's more future proof too. Like, one day users request to put multiple images on the same `exhibPost`... – Anzel Oct 22 '14 at 00:11
  • Can you give more details on that error you've got? Correct positional argument error has nothing to do with database mismatch. But I am not clear what function you're refering to – Anzel Oct 22 '14 at 00:14
  • Hmm its a feature that's been asked of me I'm afraid, plus it seems quite useful to learn how to do this dynamically. Thanks for your help, I'll keep trying. – dnv Oct 22 '14 at 00:16
  • Remember users normally don't know what's the best and they will keep asking/changing their request, on the other hand we do and that's why we're paid for. So when designing the cms, we shall implement something more future proof and flexible. Good Luck! – Anzel Oct 22 '14 at 00:18
  • where did you place the function? – Anzel Oct 22 '14 at 00:25
  • I defined it under my imports outside of the classes - though the same thing happens when defined inside the class – dnv Oct 22 '14 at 00:26
  • since you're subclassing `Orderable` I think it will involve many changes to your model. For just a simple solution, you can set your path dynamically with Y/M/D ? – Anzel Oct 22 '14 at 00:31
  • What do you think is the problem? I appreciate the help, feel free to escape if you like... – dnv Oct 22 '14 at 00:37
  • the problem is, it wouldn't catch the instance because it subclass Orderable. You need to define another __init__ to get the instance... By the way, is that FileField a django model (normally it should be models.FileField) or self declared one? it's rather late now, we can start a chat tomorrow if you want – Anzel Oct 22 '14 at 00:46
  • Mezzanine uses [this fork of django-filebrowser](https://github.com/stephenmcd/filebrowser-safe) to handle file fields, which I'm thinking is half the problem. I've just seen that it needs the callable upload_to=upload_to() to make it all link up, so somewhere between that and the subclass issue you mentioned is my problem... I might take you up on that chat if I make no progress, thanks v much – dnv Oct 22 '14 at 01:05

0 Answers0