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
Using Python weasyprint generate HTML to PDF in django

WeasyPrint is to combine multiple pieces of information into an HTML template and then converting it to a PDF document.

Continue Reading...
Basics of Django templates

Django template engine comes as part of django framework and its very easy, extensible and handy to develop complex web applications with simplest efforts. Lets ...

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

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 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