views:

44

answers:

2

For the following code:

class Image(models.Model):
   alt_name = models.CharField(max_length=200)
   url = models.CharField(max_length=255, blank=True)

class Button(Image):
   source = models.ImageField(max_length=1024, upload_to='buttons')

class Snapshot(Image):
   source = models.ImageField(max_length=1024, upload_to='snapshots')

class Banner(Image):
   source = models.ImageField(max_length=1024, upload_to='banners')

In the above cases, I want to upload each of the different kind to its own upload folder. For example, banners will go under a folder called banners and snapshot will go under snapshots. The above works as expected but I'm repeating the ImageField for each sub-class. Is the above the only way to achieve my goal or is there a DRYer method?

A: 

That is the DRYest way that I can think of.

EDIT: I realized my answer wasn't the most helpful -- sorry! However, andylei's answer would work but you still have to create your subclasses. If you are going to create the subclasses, I'd choose to be explicit. According to the Unix Philosophy, Clarity is better than Cleverness. andylei's answer may be clever, but it adds unnecessary complexity without adding any real advantage. Write your code so it is easy to be read and maintained. I could definitely see a case where you may not want to name your folder the same thing as your class name.

sheats
+5  A: 

the upload_to argument is a callable, so you can pass in a function. you could do something like this:

import os
def upload_path(instance, filename):
     return os.path.join(instance.__class__.__name__ + 's', filename)

class Image(models.Model):
    alt_name = models.CharField(max_length=200)
    url = models.CharField(max_length=255, blank=True)
    source = models.ImageField(max_length=1024, upload_to=upload_path)
andylei
.. and instead of using inheritance for each image type, i'd create an IntegerField on the Image model that includes a choices kwarg: http://docs.djangoproject.com/en/dev/ref/models/fields/#choices... Then trigger the upload_to value off the value of the IntegerField. There's no point in querying with a join on the images table if it can be avoided.
Daniel