Django Generic many to many field implementation

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.

Posted On 16 October 2012 By MicroPyramid


Need any Help in your Project?Let's Talk

Latest Comments
Factory Boy - An alternative for Fixtures

Factory Boy is a fixtures replacement tool. It allows you to use objects customized for the current test, while only declaring the test-specific fields. For ...

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

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...
Django Single Sign On(SSO) to multiple applications

Single sign on is a way for users to issue a security token for the first time login, login into multiple applications using one set ...

Continue Reading...

Subscribe To our news letter

Subscribe and Stay Updated about our Webinars, news and articles on Django, Python, Machine Learning, Amazon Web Services, DevOps, Salesforce, ReactJS, AngularJS, React Native.
* We don't provide your email contact details to any third parties