Django Rest Framework search_fields viewset from genericforeignkey field model

All models (Customer, Provider, Contact, Employee) have the same name field to search, in the main or generic model (Comments) have generic foreign key. I need search the field in the main model. It's that posible?

Models:

   class Customer(TimeStampedModel):
       name = models.CharField()

   class Provider(TimeStampedModel):
       name = models.CharField()

   class Contact(TimeStampedModel):
       name = models.CharField()

   class Employee(TimeStampedModel):
       name = models.CharField()


   class Comment(TimeStampedModel):
       content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
       object_id = models.PositiveIntegerField()
       commentator = GenericForeignKey('content_type', 'object_id')

Viewset

class CommentsViewSet(BaseViewSet):
       queryset = Comments.objects.all()
       serializer_class = CommentsSerializer
       search_fields = ["commentator__name",]

Message error:

django.core.exceptions.FieldError: Field 'commentator' does not generate an automatic reverse relation and therefore cannot be used for reverse querying. If it is a GenericForeignKey, consider adding a GenericRelation.

Upvotes: 0

Views: 1458

Answers (2)

ivissani
ivissani

Reputation: 2664

You need to add a GenericRelation field to each of your models that are able to receive comments, for instance:

   class Customer(TimeStampedModel):
       name = models.CharField()
       comments = GenericRelation('Comment', related_query_name='customer')

   class Provider(TimeStampedModel):
       name = models.CharField()
       comments = GenericRelation('Comment', related_query_name='provider')

   class Contact(TimeStampedModel):
       name = models.CharField()
       comments = GenericRelation('Comment', related_query_name='contact')

   class Employee(TimeStampedModel):
       name = models.CharField()
       comments = GenericRelation('Comment', related_query_name='employee')

Then you define your search_fields property as the list of all the related_query_names in this way:

        search_fields = ["customer__name", "provider__name", "contact__name", "employee__name"]

Please refer to this part of the documentation to know more about GenericRelation

Upvotes: 0

jimijimjim
jimijimjim

Reputation: 625

You need to add a GenericRelation to each of your models.

class Customer(TimeStampedModel):
   name = models.CharField()
   comment = GenericRelation(Comment, related_query_name='customer')

class Provider(TimeStampedModel):
   name = models.CharField()
   comment = GenericRelation(Comment, related_query_name='provider')
...

search_fields = ["customer__name", "provider__name", "contact__name", "employee_name"]

Upvotes: 0

Related Questions