Sergei
Sergei

Reputation: 390

strange behavior of django Q objects

I have 2 models:

class Call(models.Model):
    date_time_created = models.DateTimeField(auto_now_add = True)
    comment = models.CharField(max_length = 300, blank= True, null=True)
    bought_record = models.ForeignKey('BoughtRecords')

class BoughtRecords(models.Model):
    date_time_bought = models.DateTimeField(auto_now_add= True)
    bought_packet = models.ForeignKey('BoughtPackets')

I wrote 2 queries:

  1. Q1 = Q(call__result = 1)
    company_for_call = BoughtRecords.objects.exclude(Q1)

  2. company_for_call = BoughtRecords.objects.exclude(call__result = 1)

    I expected the same behaviour from this queries. They generate slightly different sql-queries( I am not good at raw sql=) ).

I suppose thats why Call not always exists for BoughtRecord or may be Q-objects not properly work with backward foreign keys. Explain me please this behaviours, because I often compile complex queries from Q-objects and sometimes get unexpected result. I want to know about situations in which at first sight result must be simular, but in reality diffent.

Upvotes: 0

Views: 114

Answers (1)

Pratik Mandrekar
Pratik Mandrekar

Reputation: 9568

I can see that in case of using Q there is an INNER_JOIN with a WHERE NOT while calling the exclude directly results in the query being a nested select. Semantically they are equivalent. When the INNER JOIN happens the NULL references on the foreign_key are excluded. In the case of nested query target_call.bought_record_id = NULL is explicitly specified. So there should not be any difference in the results.

Upvotes: 1

Related Questions