Django Generic many to many field implementation

Reading Time : ~ .

Django application has a GM2MField that combines the features of the standard Django "ManyToManyField" and "GenericForeignKey".

Installation:

pip install django-gm2m

Django’s contenttype framework must be (django.contrib.contenttypes) mentionned in the INSTALLED_APPS.

INSTALLED_APPS = [
   ...
   'django.contrib.contenttypes',
   ...
   'gm2m',
]

Uses Of django-gm2m:
1. reverse relations
2. prefetching
3. Allows you to customize the deletion behaviour

Example Models:

from django.db import models

class Videos(models.Model):
      name = models.CharField(maxlength=100)

class Articles(models.Model):
      name = models.CharField(maxlength=100)

If you want to have a field for the preferred videos and articles of a User, you need to add GM2MField to the User model.

from gm2m import GM2MField

class User(models.Model):
      email = models.CharField(maxlength=100)
      username = models.CharField(maxlength=100)
      related = models.GM2MField()

Now you can add videos, articles to the related set.
Creating User object:

user = User.objects.create(email="mp@mp.com", username="mp@mp.com")

video = Videos.objects.create(name="video")

article = Articles.objects.create(name="sample document")

user.related.add(video)

user.related.add(article)

or you can add both videos, articles instances.

user.related = [video, article]

From User instance, you can fetch all related videos, articles set or you can filter model using the "Model" or "Model__in" keywords.

list(user.related) # This provides list of model objects

list(user.related.filter(Model=Videos)) # This provides list of user related video instances

list(user.related.filter(Model__in=[Videos, Articles]))

1. Reverse Relations:

GM2MField provides automatic reverse relations when an instance is added.

We have seen how to access videos, articles of a given user.

Here we see how to access list of all the users with the given Video or Article instance.

list(video.user_set) # This provides list of user instances

With the user reverse relation, we can also use lookup chains in your queries, can also perform add, remove, clear, set operations

[each.email for each in Video.objects.filter(user__email='mp@mp.com')]


We can also list the models related to GM2MField using get_related_models method

    User.related.get_related_models()

this will give article, video objects as they are already added to user using GM2MField

2. Prefetching

GM2MField provides prefetching in the same way with ManyToManyField

    User.objects.all().prefetch_related('related')

3. Allows you to customize the deletion behaviour

    By default, when a source or target model instance is deleted, all relations linking this instance are deleted. It is possible to change this behavior with the on_delete, on_delete_src keyword arguments when creating the GM2MField.

    from gm2m.deletion import DO_NOTHING

    class User(models.Model):
          preferred_videos = GM2MField(Movie, 'Documentary', on_delete=DO_NOTHING)

    But be ensure that the database remains consistent after the deletion operation.

    By Posted On
SENIOR DEVELOPER at MICROPYRAMID

Need any Help in your Project?Let's Talk

Latest Comments
Related Articles
Django - Database access optimization Anjaneyulu Batta

Django - Database access optimization, Django Queryset is generally lazy in nature. It will not hit the database until it evaluates the query results.

Continue Reading...
E-commerce (paypal) integration with Django Ashwin Kumar

E-commerce is integration is becoming almost essential for every web application now a days. There are so many payment gateways to integrate with our application. ...

Continue Reading...
Handling Custom Error Pages(404, 500) In Django Nikhila Mergu

404 Page not found and 500 Internal server errors generally occur in every website. When these errors occurs, generally for Django application it will load ...

Continue Reading...

Subscribe To our news letter

Subscribe to our news letter to receive latest blog posts into your inbox. Please fill your email address in the below form.
*We don't provide your email contact details to any third parties