Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Example of generic relations using the contenttypes framework?

Tags:

I've pored over the Django docs regarding the contenttypes framework several times, and I simply don't understand it well enough to implement generic relations in my project. I've looked for online examples or tutorials regarding the matter, but I can't find a single one. Call me dumb, but I need some help on this one (please don't answer by simply linking to the docs). Based on the lack of resources online, I believe if you answer this question with a thorough example, your answer may be the most helpful example online to date regarding django generic relations (bonus!).

So, my question is: can someone show a simple example of the models and maybe a couple lines of code showing how to interact with instances of a generic model?


As inspiration, here is what I believe would be a very common situation:

A site has media items that are largely treated the same, but are slightly different. For example, let's say there are image and video items, and users can "like" an item or "comment" on an item. The likes and comments should be treated the same, regardless of whether they are posted on an image or video item. So, if there is an ItemView for viewing an image or a video in a user's album, the following kinds of calls would be possible : mediaitem.comments.all() or len(mediaitem.likes.all()) or comment.user_who_commented, without having to know which kind of media item it is (image or video).

I believe you would need six models for this:

  • Abstract MediaItem class
  • Two different types of media item: ImageItem and VideoItem
  • Abstract MediaItemActions class
  • Two different types of actions that can be done towards media items: Like and Comment

If you know how to use this Django feature, please show us a full example! I feel like it would be an extremely powerful tool and am aching to use it in my application. The more explicit, the better.

like image 520
sgarza62 Avatar asked Jun 06 '13 03:06

sgarza62


People also ask

What is generic relation in Django?

Generic relations. Adding a foreign key from one of your own models to ContentType allows your model to effectively tie itself to another model class, as in the example of the Permission model above.

What are Django Contenttypes?

Content types are Django's way of identifying database tables. Every Database table is represented as a row in the content type table which is created and maintained by Django.

What is Django_content_type table?

ContentType is just a model and table in the database that contains information about all the other tables/models in your django application. Postgres table: => \d django_content_type; Column | Type | Modifiers -----------+------------------------+----------------------------------------- id | integer | not null ...


1 Answers

Your use case sounds very similar to the (now deprecated) Django comments framework. If you check out the models, you'll see how to use a generic relation in BaseCommentAbstractModel--note that you need all three fields, a ForeignKey to ContentType, a field to hold the objects' pks, and the GenericForeignKey field.

As for how to query for objects by GenericForeignKey, you can see some examples in the template tags in that project. See for example the get_query_set method in BaseCommentNode, which retrieves comments by querying on the content type and pk of the target object.

def get_query_set(self, context):
    ctype, object_pk = self.get_target_ctype_pk(context)
    if not object_pk:
        return self.comment_model.objects.none()

    qs = self.comment_model.objects.filter(
        content_type = ctype,
        object_pk    = smart_text(object_pk),
        site__pk     = settings.SITE_ID,
    )
like image 71
Michael C. O'Connor Avatar answered Oct 23 '22 01:10

Michael C. O'Connor