14

我有一个 Abstract 基本模型和 2 个继承模型,我需要强制 related_name 采用特定格式。

class Animal(models.Model):
    legs = models.IntegerField(related_name='%(class)s')
    habitat = models.ForeignKey(Habitats, related_name='%(class)s')

class DogAnimal(BaseModel):
    name = models.CharField(max_length=20, related_name='dog_animal')

class CatAnimal(BaseModel):
    name = models.CharField(max_length=20, related_name='cat_animal')

通常,related_name = '%(class)s' 将分别导致 catanimal 和 doganimal。

我需要像这样的下划线值:dog_animal,cat_animal

这是我需要这样做的“原因”-Legacy。这些模型不是用基类组织的——所以最初指定的related_name 是“dog_animal”和“cat_animal”。改变这将是很多工作。

4

2 回答 2

10

一个解决方案可能不是为所有孩子指定related_nameforhabitat并定义 a :default_related_name

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'
于 2018-10-17T09:23:42.157 回答
2

它需要一些调整,但我认为你可以通过覆盖ForeignKey类来做到这一点:

from djang.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)
        related_name = self.remote_field.related_name
        if not cls._meta.abstract and related_name:
            underscore_name = camel_case_to_spaces(cls.__name__).replace(' ', '_')
            self.remote_field.related_name = related_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}')
于 2018-10-17T09:18:27.760 回答