2

I have a model below which points to a generic relationship. This can either be a Post object or a Reply object.

class ReportedContent(models.Model):

    reporter = models.ForeignKey(User, on_delete=models.CASCADE)

    # Generic relation for posts and replies
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey()

    class Meta:
        unique_together = ('reporter', 'object_id', 'content_type')

I would like to check if the content_object is already exists before I get a duplicate key value violates unique constraint exception.

Django documentation mentioned that:

# This will fail
>>> ReportedContent.objects.filter(content_object=content)
# This will also fail
>>> ReportedContent.objects.get(content_object=content)

So how can I filter on generic relation? or how can I deal with this exception specifically?

Aymane Max
  • 182
  • 11
  • This seems like it would be a headache. Why not have two foreign key fields, one for a `Post` and one for a `Reply`, and validate that exactly one of the two fields has a value? – Jessie May 24 '19 at 04:05
  • @user2896976 that pretty much easier,thank u – Aymane Max May 24 '19 at 19:14

2 Answers2

1

you can filter by object_id and content_type. just make sure you do it right, get content_type this way:

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

content_type = ContentType.objects.get(app_label='name_of_your_app', model='model_name')

for handling the exception :

if ReportedContent.objects.filter(object_id=content.id,content_type=content_type):
    raise Exception('your exception message')
Aymane Max
  • 182
  • 11
0

I realize this is an old(ish) question, but I thought I'd offer an alternative method in case others run across this post as I did.

Instead of doing a separate .get() on the ContentType model, I just incorporate the app/model names in my filter, like this:

queryset = ReportedContent.objects.filter(
               object_id=parent_object.id,
               content_type__app_label=app_label,
               content_type__model=model_name
           )
ExTexan
  • 373
  • 2
  • 18