1

Suppose I have the following database structure:

class Asset(models.Model):
    # ...

class AbstractBuilding(models.Model):
    asset = models.OneToOneField(Asset, on_delete=models.CASCADE, primary_key=True)
    # ...

    class Meta:
        abstract = True


class Office(AbstractBuilding):
    # ...


class Lab(AbstractBuilding):
    # ...


class PowerPlant(AbstractBuilding):
    # ...

If I have an Office object, it's easy to get the corresponding Asset through the one-to-one field (e.g. office_object.asset returns an Asset). However, suppose I have a Asset instead. How can I get the corresponding Office (or Lab or PowerPlant) from the Asset object?

Flux
  • 9,805
  • 5
  • 46
  • 92
  • Related: [How do I access the child classes of an object in django without knowing the name of the child class?](https://stackoverflow.com/questions/929029/) – Flux Dec 12 '19 at 15:08
  • Related: [Django: Get all implementations of an Abstract Base Class](https://stackoverflow.com/questions/1729784/) – Flux Dec 12 '19 at 15:10

1 Answers1

1
# You have an instance of Asset e.g.
asset = Asset.objects.first()

office = getattr(asset, "office") # gives you related office if it is related to office

lab = getattr(asset, "lab") # gives you related lab if it is related to lab

power_plant = getattr(asset, "powerplant") # gives you related powerplant if it is related to powerplant

Nader Alexan
  • 2,127
  • 22
  • 36
  • You may want to add an example of catching `django.core.exceptions.ObjectDoesNotExist` if the `getattr` fails to get the specified related object. – Flux Dec 10 '19 at 23:50
  • Or even better: `office = getattr(asset, Office.__name__.lower())`. This avoids having to fiddle with strings. – Flux Jan 02 '20 at 22:45