Search code examples
djangodjango-contenttypesgeneric-foreign-key

Use Django GenericForeignKey to store basic notifications


I've used Django quite a bit and I'm fairly familiar with models. However, I've just come across the GenericForeignKey and ContentTypes framework.

I'm planning to use these to store basic notifications that reference a few other models.

For example, I have the following models

class UserFollowers(models.Model): #Model to store which user follows others
    ...

class ContactShared(models.Model): #Model to store contact requests between users
    ...

Now on each of these actions by one user, the other involved user gets a notification. I've completed the real time aspect of these by using a Node server and socket.io. However, to achieve this same behaviour for users who aren't online at the moment, I came across the above mentioned Generic Foreign key and ContentTypes.

My question here is,since the documentation was not too clear about this, I would like to know how to use these two features to store the user activities?


Solution

  • I'm actually new to this but I used a little bit of this before, so I just share my experience with GenericForeignKey.

    Basically you want to define the content type and the id fields in the model, then a third field to combine them so that you could easily look it up later on, like this:

    class UserActivity(models.Model):
        activity_ct = models.ForeignKey(ContentType)
        activity_id = models.PositiveIntegerField()
        activity = generic.GenericForeignKey('activity_ct', 'activity_id')
    

    When you save/query, you do this:

    from django.contrib.contenttypes.models import ContentType
    
    activity_obj = UserFollowers.objects.get(id=1)
    activity_ct = ContentType.objects.get_for_model(activity_obj)
    activity_create = UserActivity.objects.create(activity_ct=activity_ct, 
                                                  activity_id=activity_obj.id)
    activity_query = UserActivity.objects.filter(activity_ct=activity_ct,
                                                 activity_id=activity_obj.id)
    

    The good part is that when you want to pull the UserActivity's activity object, you can just do activity_obj.activity. I'm not sure if it's exactly your plan but the mechanism is the same. Hope this helps.