from django.db.models import F qset = Coding.objects.filter(response__coding__value__gt=F('value') + 1, qid='risk', coder=4 ).extra(where=['T3.qid = %s', 'T3.coder_id = %s'], params=['risk', 3]) responses = [c.response for c in qset.select_related('response')]
When you join a table already in the query, ORM will assign a second alias, in this case T3, which you can use in the parameters for extra() . To find out what an alias is, you can get into the shell and print qset.query .
See Django documentation on F and extra objects
Update: It doesn't seem like you need to use extra() or figure out which alias django is using, because every time you refer to response__coding in your searches, django will use the originally created alias. Here is one way to look for differences in any direction:
from django.db.models import Q, F gt = Q(response__coding__value__gt=F('value') + 1) lt = Q(response__coding__value__lt=F('value') - 1) match = Q(response__coding__qid='risk', response__coding__coder=4) qset = Coding.objects.filter(match & (gt | lt), qid='risk', coder=3) responses = [c.response for c in qset.select_related('response')]
See Django's Q Objects documentation
BTW. If you need both instances of the encoding, you have a problem with N + 1, because django select_related() will not get FK backward relationships. But since you already have the data in the request, you can get the necessary information using the T3 alias, as described above, and extra(select={'other_value':'T3.value'}) . The value data from the corresponding encoding record will be available as an attribute in the extracted encoding instance, that is, as c.other_value .
By the way, your question is quite general, but it looks like you have an entity-attribute-value attribute schema, which in an RDB script is usually considered an anti-pattern. You might be better off in the long run (and this query will be easier) with the risk field:
class Coding(models.Model): response = models.ForeignKey(Response) coder = models.ForeignKey(User) risk = models.IntegerField()