13👍
A solution might be not to specify the related_name
for habitat
and define a default_related_name
for all children:
class Animal(models.Model):
class Meta:
abstract = True
habitat = models.ForeignKey(Habitats, on_delete=models.CASCADE)
class DogAnimal(Animal):
class Meta:
default_related_name = 'dog_animal'
class CatAnimal(Animal):
class Meta:
default_related_name = 'cat_animal'
2👍
It requires a little tweak, but I think you can do this by overriding the ForeignKey
class:
from django.utils.text import camel_case_to_spaces
class MyForeignKey(models.ForeignKey):
def contribute_to_class(self, cls, *args, **kwargs):
super().contribute_to_class(cls, *args, **kwargs)
if not cls._meta.abstract:
related_name = self.remote_field.related_name
related_query_name = self.remote_field.related_query_name
underscore_name = camel_case_to_spaces(cls.__name__).replace(" ", "_")
if related_name:
self.remote_field.related_name = related_name.format(
underscore_name=underscore_name
)
if related_query_name:
self.remote_field.related_query_name = related_query_name.format(
underscore_name=underscore_name
)
class Animal(models.Model):
class Meta:
abstract = True
habitat = MyForeignKey(
Habitats, on_delete=models.CASCADE, related_name="{underscore_name}"
)
Source:stackexchange.com