Django ORM Cookbook
  • Introduction
  • 1. How to find the query associated with a queryset?
  • 2. How to do OR queries in Django ORM?
  • 3. How to do AND queries in Django ORM?
  • 4. How to do a NOT query in Django queryset?
  • 5. How to do union of two querysets from same or different models?
  • 6. How to select some fields only in a queryset?
  • 7. How to do a subquery expression in Django?
  • 8. How to filter a queryset with criteria based on comparing their field values
  • 9. How to filter FileField without any file?
  • 10. How to perform join operations in django ORM?
  • 11. How to find second largest record using Django ORM ?
  • 12. Find rows which have duplicate field values
  • 13. How to find distinct field values from queryset?
  • 14. How to use Q objects for complex queries?
  • 15. How to group records in Django ORM?
  • 16. How to efficiently select a random object from a model?
  • 17. How to use arbitrary database functions in querysets?
  • 1. How to create multiple objects in one shot?
  • 2. How to copy or clone an existing model object?
  • 3. How to ensure that only one object can be created?
  • 4. How to update denormalized fields in other models on save?
  • 5. How to perform truncate like operation using Django ORM?
  • 6. What signals are raised by Django during object creation or update?
  • 7. How to convert string to datetime and store in database?
  • 1. How to order a queryset in ascending or descending order?
  • 2. How to order a queryset in case insensitive manner?
  • 3. How to order on two fields
  • 4. How to order on a field from a related model (with a foreign key)?
  • 5. How to order on an annotated field?
  • 1. How to model one to one relationships?
  • 2. How to model one to many relationships?
  • 3. How to model many to many relationships?
  • 4. How to include a self-referencing ForeignKey in a model
  • 5. How to convert existing databases to Django models?
  • 6. How to add a model for a database view?
  • 7. How to create a generic model which can be related to any kind of entity? (Eg. a Category or a Comment?)
  • 8. How to specify the table name for a model?
  • 9. How to specify the column name for model field?
  • 10. What is the difference between null=True and blank=True?
  • 11. How to use a UUID instead of ID as primary key?
  • 12. How to use slug field with django for more readability?
  • 13. How to add multiple databases to the django application ?
  • 1. How to assert that a function used a fixed number of queries?
  • 2. How to speed tests by reusing database between test runs?
  • 3. How to reload a model object from the database?
Django ORM Cookbook
  • Books »
  • Django ORM Cookbook »
  • 7. How to create a generic model which can be related to any kind of entity? (Eg. a Category or a Comment?)
  • hello@agiliq.com

7. How to create a generic model which can be related to any kind of entity? (Eg. a Category or a Comment?)¶

You have models like this.

class Category(models.Model):
    name = models.CharField(max_length=100)
    # ...

    class Meta:
        verbose_name_plural = "Categories"


class Hero(models.Model):
    name = models.CharField(max_length=100)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    # ...


class Villain(models.Model):
    name = models.CharField(max_length=100)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    # ...

Category can be applied as a generic model. You prbably want to be able to apply categories to objects form any model class. You can do it like this

from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
# ...

class FlexCategory(models.Model):
    name = models.SlugField()
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')


class Hero(models.Model):
    name = models.CharField(max_length=100)
    flex_category = GenericRelation(FlexCategory, related_query_name='flex_category')
    # ...


class Villain(models.Model):
    name = models.CharField(max_length=100)
    flex_category = GenericRelation(FlexCategory, related_query_name='flex_category')
    # ...

What did we do, we added a GenericForeignKey fields on FlexCategory using one ForeignKey and one PositiveIntegerField, then added a GenericRelation on the models you want to categorize.

At the database level it looks like this:

You can categorize a Hero like this.

FlexCategory.objects.create(content_object=hero, name="mythic")

And then get a Hero categorised as ‘ghost’ like this

FlexCategory.objects.create(content_object=hero, name="ghost")

This gives us this sql.

SELECT "entities_hero"."name"
FROM "entities_hero"
INNER JOIN "entities_flexcategory" ON ("entities_hero"."id" = "entities_flexcategory"."object_id"
                                       AND ("entities_flexcategory"."content_type_id" = 8))
WHERE "entities_flexcategory"."name" = ghost
Next Previous

© Copyright 2018, Agiliq Revision d882d2fe.

Read more books at https://books.agiliq.com

Read the Docs v: latest
Versions
latest
Downloads
pdf
html
epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.