Rajeshwar
Rajeshwar

Reputation: 11661

Django Q object query filtering with multiple conditions failing

I am trying to apply multiple conditions to my filter. The model looks like this

class modelChat(models.Model):
    source              = models.ForeignKey(modelEmployer,related_name = 'rsource',on_delete=models.CASCADE,null=True,default=None,blank=True)
    job                 = models.ForeignKey(modelJob,on_delete=models.CASCADE,null=True,default=None,blank=True)
    destination         = models.ForeignKey(modelEmployer,related_name = 'rdestination',on_delete=models.CASCADE,null=True,default=None,blank=True)

Initially I am trying to obtain an instance of chat that involves 2 parties based on a job. At one point source can be a destination and sometimes the destination can be the source. but the job remains the same.

This is what my query looks like

querySet = modelChat.objects.filter(
                      (Q(source=modelEmployerSourceInstance) | Q(destination=modelEmployerSourceInstance))
                                      &
        (Q(destination=modelEmployerDestinationInstance) | Q(destination=modelEmployerDestinationInstance))
                                      &
                              Q(job_id=job_id)
                                       )

The job id is correct and I know there is only one item in the DB. However this query alway returns back an empty item. Any suggestions why this is wrong and how I can fix it ?

Upvotes: 4

Views: 7284

Answers (1)

bruno desthuilliers
bruno desthuilliers

Reputation: 77912

I can't say for sure if that's the problem since you forgot to show what you really have in your DB but here:

(Q(destination=modelEmployerDestinationInstance) |   Q(destination=modelEmployerDestinationInstance))

I assume you want:

(Q(source=modelEmployerDestinationInstance) |   Q(destination=modelEmployerDestinationInstance))

instead...

Note that the logical would be much more obvious with shorter names, ie source and destination instead of modelEmployerSourceInstance modelEmployerDestinationInstance:

q = (
        (Q(source=source) | Q(destination=source))
      & (Q(source=destination | Q(destination=destination))
      & Q(job_id=job_id)
    )
querySet = modelChat.objects.filter(q)

Meaningful names are a good thing, but they have to be short and distinct enough. With "modelEmployerXXXInstance", you have four words to parse, and with the only distinctive (hence relevant) part of the name being in third position, your brain tends to skip over this part. The "model", "Employer" and "Instance" parts are actually just noise.

Upvotes: 5

Related Questions