0

I have a situation I don´t know how to model correctly. I want every child of a class to be associated with a media object (photo, video or music). I want to know which is the preffered approach to this problem. What I have right now is:

class Something(models.Model):

    media = models.ForeignKey(Media)


class Media(models.Model):
    title = models.CharField(max_lenght=100)
    def get_tiny_object():
        pass
    def get_big_object():
        pass

class Picture(Media):
    picture = models.ImageField()
    def get_tiny_object():
        return ...
    ...

class Video(Media):
    video = models.CharField(max_length=200) #youtube id
    ...

class Music(Media):
    music = ....

You get the idea. ¿Does this work? Should I also record on "Something" what kind of media it is?

EDIT:

The idea behind having a Media class, is that I can render in the templates without knowing which kind of media I´m rendering. get_tiny_object() should return, if it is a picture:

"<img style="width:60px; height: 50px" ...>"

So if I have a foreign key to a media object lets say it's id=4, does django know that it should be fetched from music table, if the object I associated with is of Music kind? Because I´ll have 3 different id=4, one on each table (picture, video and music (and possibly more if the domain changes)).

4
  • What's the purpose of the Media class? Is it just to document an interface, or is there common implementation code, or to save a tiny bit of typing (the title field there) Commented May 3, 2011 at 1:16
  • @Henry I think OP wants to know if the usual inheritance can be done in Django models. Is that correct? Personally, I would say it is a good practice to have such structure, a.k.a. make use of OOP where it makes the solution elegant and maintainable. Commented May 3, 2011 at 1:55
  • 1
    @geekam the inheritance can be done with Django for sure, in a number of ways including straight inheritance. I think we cannot say what is good practice until we understand the intent of the code better, but best guess given how he's approaching it is multi-table inheritance, which he's already doing... Commented May 3, 2011 at 3:00
  • the purpuse of media class is that I can call get_tiny_object() without knowing if it is a picture, a video or a music and render it. get_tiny_object() should return a <img> or <object>, so that the template can be agnostic of the type of media it is. Commented May 3, 2011 at 3:12

2 Answers 2

2

I still think the question is a little hard to understand - the title is Database modelling in Django after all...However, this is a perfectly valid and reasonable thing to do, and seems to fit your intent:

The recommended way to do this is multi table inheritance - example:

class Media(models.Model):
    pass

class Something(models.Model):
    media = models.ForeignKey(Media)

class Picture(Media):
    foo = models.CharField(max_length=100)

    def get_tiny_object(self):
        return self.foo

class Video(Media):
    bar = models.CharField(max_length=100)

    def get_tiny_object(self):
        return self.bar

picture = Picture.objects.create(foo='some picture')
video = Video.objects.create(bar='some video')
something1 = Something.objects.create(media=picture)
something2 = Something.objects.create(media=video)
print something1.media.get_tiny_object() # this is a picture remember?
print something2.media.get_tiny_object() # and lo, here is a video
Sign up to request clarification or add additional context in comments.

3 Comments

oh, btw why is the title strange? Isn´t it the database schema <-> orm modeling?
The title should ideally be phrased as a question. Example: How do I create a single foreign key relationship to multiple model types using Django? Although I'm not sure if that is the question, so you should write it :)
yea, @Henry is right, there are some general discussions and community wikis here as well.
0

http://docs.djangoproject.com/en/dev/topics/db/models/#one-to-one-relationships

this says you should use a OneToOneField relating each Picture, Video, Music to a Media entry, and they all inherit directly from models.Model.

Also, you need to change your Something to

class Something(models.Model):

    media = models.ForeignKey("Media")

because since Media isn't defined when you define Something (if you place it below it), it won't work, django provides you with the possibility of doing this with the classname instead of a reference to the class

5 Comments

I don't really agree, according to docs.djangoproject.com/en/dev/topics/db/models/… you could do multi-table inheritance for a very similar effect...
The "Media" thing was just a simplification. They are on separate files and there are imports involved, but thanks for the concern.
@Henry: you're right, I hadn't read that. Thanks for the correction
hm.. it's exactly the same.. "The inheritance relationship introduces links between the child model and each of its parents (via an automatically-created OneToOneField)"
It's not exactly the same. It may create the same SQL relations, but you have to manually manage it and cannot use Picture and Video interchangeably in place of a Media object. The inheritance gives Django a bit hint to take care of it for you.

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.