0

I have the following Django models:

class Image(TimeStamp):
     hash = models.CharField(max_length=33,
                            unique=True,
                            editable=False)

     filesize = models.PositiveIntegerField(blank=True,
                                           null=True,
                                           editable=False)

class Image1(Image):
    image = models.ImageField(upload_to='image1/')

class Image2(Image):
    image = models.ImageField(upload_to='image2/')

I want to be able to automatically compute filesize and hash upon image creation and the most reasonable place seems to me in a super class. However, I need to be able to access child class image field from the super class in order to compute hash and filesize. Is there a way to achieve this?

I added this save method to the superclass, but of course it doesn't know about image:

def save(self, *args, **kwargs):
    super(Image, self).save(*args, **kwargs)

    self.hash = hashlib.md5(self.image.read()).hexdigest()
    self.filesize = self.image.size
4
  • Did you try making an image field in the parent? Then you're simply overriding the upload_to in each child. Commented Oct 26, 2017 at 18:00
  • 2
    Is the only difference between those models the upload_to location? If so you should just use a single model with a callable for that attribute. Commented Oct 26, 2017 at 18:18
  • Yes, upload_to is the only thing in common for now, but later I might add different height, width and max_file_size arguments to different child classes. Commented Oct 27, 2017 at 8:30
  • Is it worth introducing new DB fields for those so that they can be overridden? (I meant max_length, height_field and width_field of the models.ImageField in the previous comment) Commented Oct 27, 2017 at 8:37

1 Answer 1

1

Here's what I ended up doing to solve this. Thank everyone for the feedback and please let me know if this code can be improved further:

def get_image_directory(instance, filename):
    return os.path.join(instance.upload_to, filename)


class Image(TimeStamp):
    hash = models.CharField(max_length=33,
                            unique=True,
                            editable=False)

    file_size = models.PositiveIntegerField(blank=True,
                                           null=True,
                                           editable=False)

    image = models.ImageField(upload_to=get_image_directory)

    def __str__(self):
        return self.image.url.split('?')[0]

    def save(self, *args, **kwargs):
        self.hash = hashlib.md5(self.image.read()).hexdigest()
        self.file_size = self.image.size
        super(Image, self).save(*args, **kwargs)

    class Meta:
        abstract = True


class Image1(Image):
    upload_to = 'image1/'

class Image2(Image):
    upload_to = 'image2/'
Sign up to request clarification or add additional context in comments.

Comments

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.