In general, it is not possible to go through the GenericForeignKey in this direction the way you are trying. A GenericForeignKey can point to any model in your application in general, and not just Bar and its subclasses. For this reason, Foo.objects.filter(bar__somefield='some value') cannot know which target model you have in mind at the moment, and therefore it is not possible to determine which fields have target models. In fact, there is no way to choose which database table you can join with when performing such a query - it can be any table depending on the value of Foo.content_type .
If you want to use a generic relation in joins, you will need to define a GenericRelation at the other end of this relationship. That way, you can let Django know which model it should look for on the other side.
For example, you can create your BarX and BarY as follows:
class BarX(Bar): name = models.CharField(max_length=10, default='bar x') foos = GenericRelation(Foo, related_query_name='bar_x') class BarY(Bar): name = models.CharField(max_length=10, default='bar y') foos = GenericRelation(Foo, related_query_name='bar_y')
If you do this, you can perform queries such as:
Foo.objects.filter(bar_x__name='bar x') Foo.objects.filter(bar_y__name='bar y')
However, you need to select one target model. This is a limitation that you cannot overcome in any way; Each database connection must know in advance in which tables it works.
If you absolutely must allow both BarX and BarY as the target, you must specify them explicitly in your request filter using Q :
Foo.objects.filter(Q(bar_x__name='bar x') | Q(bar_y__name='bar y'))
source share