I am new to Django, and not very advanced at this point.
My goal is to make one "Comment" model that works for different "Post" models.
My structure is as follows:
class TunedCarPost(models.Model):
.....
.....
class ConceptCarPost(models.Model):
.....
.....
class ArticlePost(models.Model):
.....
.....
class Comment(models.Model):
post = models.ForeignKey(
[TunedCarPost, ConceptCarPost, ArticlePost],
related_name="comments",
on_delete=models.CASCADE,
)
.....
.....
I can't do such thing as:
class Comment(models.Model):
post = models.ForeignKey(
[TunedCarPost, ConceptCarPost, ArticlePost],
related_name="comments",
on_delete=models.CASCADE,
)
I tried to use an abstract model, so "Comment" only links to the abstract model:
class Post(models.Model):
.....
.....
class TunedCarPost(Post):
.....
.....
class ConceptCarPost(Post):
.....
.....
class ArticlePost(Post):
.....
.....
class Comment(models.Model):
post = models.ForeignKey(
Post,
related_name="comments",
on_delete=models.CASCADE,
)
.....
.....
But Django throws an exception that ForeignKey can't link to an abstract model.
Is there any easy solutions for my case or my structure is total mess?
There are some different options to achieve this:
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models
class Comment(models.Model):
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"]),
]
This means that each Comment
instance stores the content_type
of related model e.g. TunedCarPost
and primary key (object_id
) of that particular instance.
To create a new comment:
tuned_car_post = TunedCarPost.objects.get(pk=1)
comment = Comment(content_object=tuned_car_post)
comment.save()
To access the content object
comment.content_object
class TunedCarPost(models.Model):
comments = models.ManyToManyField(Comment)
class ConceptCarPost(models.Model):
comments = models.ManyToManyField(Comment)
class ArticlePost(models.Model):
comments = models.ManyToManyField(Comment)
This would mean that each one of the post types would have their own comments database table.