views:

20

answers:

3

I have multiple models which all have a FK to the same model. All I know is the FK how can I determine which of the models has the FK attached?

Below an example to clearify:

class ModelA(models.Model):
      title = models.CharField("title", max_length=80)

class ModelB(models.Model):
      fk = models.ForeignKey(ModelA)

class ModelC(models.Model):
      fk = models.ForeignKey(ModelA)

How can I figure out without using a try/except on each model whether B or C has the FK? (The FK can only be in one of them, for the record in this case I only added two models but in the real world app there are multiple possible x amount of models which have the FK to modelA)

A: 
if ModelB.objects.filter(fk=your_fk):
   print "B"
else:
   print "C"

if you're unsure whether this fk is present in either B or C at all, add another check:

if ModelB.objects.filter(fk=your_fk):
   print "B"
elif ModelC.objects.filter(fk=your_fk):
   print "C"
else:
   print "none"
Antony Hatchkins
But I feel that is too similar to try/except you mentioned. What's wrong with try/except? You want to use a single database query to check both results?
Antony Hatchkins
lets assume I have 20 models, I don't want to try/except all of them. I was wondering is there a way to query to check all the models for a result. Otherwise I have to make an intermediate model.
swoei
What is your intention - time optimization (to make one complex request instead of 20 simple) or just a syntactic convenience?
Antony Hatchkins
A: 

If as you said you have many models with foreignkeys to ModelA maybe you should consider having a field in ModelA which caches this information? It could be updated by save() method of ModelB/C/.. or by a database stored procedure.

Antony Hatchkins
How about this answer?
Antony Hatchkins
A: 

If you're after syntactic sugar and reducing number of queries try this:

a=ModelA.objects.annotate(nb=Count('modelb'), nc=Count('modelc')).get(pd=your_fk)
if a.nb:
    return 'B'
elif a.nc:
    return 'C'
else:
    return 'A'

(django >= v1.1)

Antony Hatchkins