Search code examples
djangodjango-templatesdjango-contenttypes

Confused about ContentType


Suppose this is a model for a user's photo:

class Photo(models.Model):
    user = models.ForeignKey(User)
    title = models.CharField()
    image = models.ImageField()
    pub_date = models.DateTimeFied(auto_now=True, auto_now_add=pub_date)
    update = models.DateTimeFied(auto_now=False, auto_now_add=True)

This is another model for user's status:

class Status(models.Model):
        user = models.ForeignKey(User)
    tweet = models.TextFied()
    pub_date = models.DateTimeFied(auto_now=True, auto_now_add=pub_date)

Now, this is a model for all the feeds of a user:

class StreamItem(models.Model):
    user = models.ForeignKey(User)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type','object_id')
  1. In the above class StreamItem, will the content_type be the data_type of the instance?

  2. What is object_id? Is it the pk of the content_type instance or the pk for that StreamItem instance?

  3. How do I get the pub_date of the content_type instance (Photo and Status) and initialize it to the StreamItem instance?

  4. Lastly, how do I render it in the template? Because I don't know whether it is a text or an image.

Thank you.


Solution

  • This is a really quick answer:

    1) content_type will be the object type (Photo or Status in your case), see Django contenttypes framework for more on how that works.

    2) object_id will be the primary key of the Photo or Status

    3) To access the properties of the generic, access them through your content_object property

    stream_item.content_object.pub_date
    

    4) I would make a method on each model for the way you want it rendered. This could be used in conjunction with python's template system. Name the methods the same that way you can call it like an interface.

    class Status(models.Model):
        ...
        def render_widget(self):
            return render_to_string('status_widget.html', {'status' : self })
    
    
    class Photo(models.Model):
        ...
        def render_widget(self):
            return '<span>My HTML Here</span>'
    

    For Use in Your Template:

    {% for item in stream_items %}
        {{ item.content_object.render_widget }}
    {% endfor %}