1

I'm writing Django app, I want to create different directory for every different Trip.

This code doesn't work (using method):

class TripPhoto(models.Model):
    def __str__(self):
        return self.trip_id.title
    trip_id = models.ForeignKey(Trip, on_delete=models.CASCADE)
    def get_trip_title(self):
        return self.trip_id.title
    photo = models.ImageField(upload_to="reservations/" + get_trip_title() + "/") # NEED FIX

photo = models.ImageField(upload_to="reservations/" + get_trip_title() + "/") # NEED FIX TypeError: get_trip_title() missing 1 required positional argument: 'self'

This code doesn't work too (using attribute):

class TripPhoto(models.Model):
    def __str__(self):
        return self.trip_id.title
    trip_id = models.ForeignKey(Trip, on_delete=models.CASCADE)
    photo = models.ImageField(upload_to="reservations/" + str(trip_id.title) + "/") # NEED FIX

photo = models.ImageField(upload_to="reservations/" + str(trip_id.title) + "/") # NEED FIX AttributeError: 'ForeignKey' object has no attribute 'title'

I know that I can use self.trip_id.title, because I used it in another part of the code.

Is there any way to use self (instance reference?) outside of class method?

3
  • the problem is that the upload_to argument is passed (and computed) on class initiation. at that time, there are no instances of TripPhoto at all, and therefore, no self, no trip_id and no trip title. cosider changing your design for not requiring that (or, don't use the image field to store the image) Commented Mar 7, 2018 at 13:28
  • 1
    @Mr.Nun. Actually neverwalkaloners answer is pretty good. Commented Mar 7, 2018 at 13:46
  • 1
    It is. apparently, Imagefield is able to use a 'callable' that gets instance and filename which is independent on the TripPhoto instance. however. regarding you question, it is still not possible to refer to the instance 'self' the way you want to. Commented Mar 7, 2018 at 13:51

1 Answer 1

3

Declare function outside of the model, instance will be passed to it with first argument:

def get_trip_title(instance, filename):
    # file will be uploaded to MEDIA_ROOT/reservations/title/<filename>
    return 'reservations/{0}/{1}'.format(instance.trip_id.title, filename)

class TripPhoto(models.Model):
    photo = models.FileField(upload_to=get_trip_title)
Sign up to request clarification or add additional context in comments.

1 Comment

Your answer is not exactly what I was looking for, but it works perfectly for me, so upvote :). But I guess that there is probably no way to call something like self outside method..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.