from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
class Comment(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
text = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
# Generic foreign key fields
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
class Meta:
indexes = [
models.Index(fields=['content_type', 'object_id']),
]
from django.db import models
from django.contrib.contenttypes.fields import GenericRelation
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
# Reverse generic relation
comments = GenericRelation('comments.Comment')
def get_comments(self):
return self.comments.all().select_related('author')
from blog.models import Post
from products.models import Product
from comments.models import Comment
# Add comment to a post
post = Post.objects.get(id=1)
Comment.objects.create(
author=user,
text='Great post!',
content_object=post
)
# Add comment to a product
product = Product.objects.get(id=1)
Comment.objects.create(
author=user,
text='Love this product!',
content_object=product
)
# Query comments
post_comments = Comment.objects.filter(
content_type=ContentType.objects.get_for_model(Post),
object_id=post.id
)
ContentTypes enable generic foreign keys pointing to any model. I use GenericForeignKey for features like comments, tags, or favorites on multiple content types. The framework tracks all installed models. I query with content_type and object_id. For reverse relations, I use GenericRelation. This is powerful but harder to query than regular foreign keys. I'm careful about database joins and prefetching. Use cases include activity streams, notifications, and polymorphic associations.