Given:
from django.db import models class Food(models.Model): '''Food, by name.''' name = models.CharField(max_length=25) class Cat(models.Model): '''A cat eats one type of food''' food = models.ForeignKey(Food) class Cow(models.Model): '''A cow eats one type of food''' food = models.ForeignKey(Food) class Human(models.Model): '''A human may eat lots of types of food''' food = models.ManyToManyField(Food)
How can one, given only the class Food, get a set of all classes that it has ‘reverse relationships’ to. I.e. given the class Food, how can one get the classes Cat, Cow and Human.
I would think it’s possible because Food has the three ‘reverse relations’: Food.cat_set, Food.cow_set, and Food.human_set.
Help’s appreciated & thank you!
Either
A) Use multiple table inheritance and create a ‘Eater’ base class, that Cat, Cow and Human inherit from.
B) Use a Generic Relation, where Food could be linked to any other Model.
Those are well-documented and officially supported features, you’d better stick to them to keep your own code clean, avoid workarounds and be sure it’ll be still supported in the future.
— EDIT ( A.k.a. ‘how to be a reputation whore’ )
So, here is a recipe for that particular case.
Let’s assume you absolutely want separate models for Cat, Cow and Human. In a real-world application, you want to ask to yourself why a ‘category’ field wouldn’t do the job.
It’s easier to get to the ‘real’ class through generic relations, so here is the implementation for B. We can’t have that ‘food’ field in Person, Cat or Cow, or we’ll run into the same problems. So we’ll create an intermediary ‘FoodConsumer’ model. We’ll have to write additional validation tests if we don’t want more than one food for an instance.
Now, to demonstrate it let’s just write this working doctest: