In Django, I have an abstract class:
class AbstractResult(models.Model):
specimen = models.ForeignKey(Specimen, on_delete=models.CASCADE, related_name='%(class)s')
...
class Meta:
abstract = True
This gives me some control over the related name of this field for each concrete class, but not full control. I'd like to be able to set this name in each concrete class.
I thought maybe I could use a callable:
class AbstractResult(models.Model):
def get_related_name(self):
raise NotImplementedError("Override this method in your concrete model classes!")
specimen = models.ForeignKey(Specimen, on_delete=models.CASCADE, related_name=get_related_name)
But that didn't work, as the related_name arg doesn't take a callable.
I also thought maybe I could do:
class AbstractResult(models.Model):
related_name = 'OVERRIDE THIS ATTRIBUTE!'
specimen = models.ForeignKey(Specimen, on_delete=models.CASCADE, related_name=related_name)
and then try to use it in the concrete class:
class TestA_Result(AbstractResult):
related_name = "test_a_results"
but that didn't work either. Why didn't that work? Is there any simple way to make it work?
Update:
It looks like the "problem" is that the related_name=related_name in my last example gets evaluated when the AbstractResult class is being constructed - not when the TestA_Result class is being constructed. This isn't a Django thing - this is just how Python works:
class AbstractClass:
field_one = 'field one set in abstract class'
field_two = field_one
class ConcreteClass(AbstractClass):
field_one = 'set in concrete class'
inst = ConcreteClass()
inst.field_one # 'set in concrete class'
inst.field_two # 'field one set in abstract class'
Is there a way around this that would allow me to set the related_name in Django's concrete class?