Как установить related_name в поле ManyToMany в абстрактной модели? - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть эта абстрактная модель:

class HasSystemMessage(models.Model):
    class Meta:
        abstract = True

    messages = models.ManyToManyField(SystemMessage, related_name=?)

Я собираюсь использовать эту абстрактную модель как минимум в трех других моделях, скажем, A, B и C. Как я могу динамически установить related_name для этих классов? например, для класса B я хочу, чтобы related_name было Bs. Возможно ли это сделать?

Чтобы прояснить вопрос, классы будут выглядеть так:

class B(HasSystemMessage):
    # Some model fields 
class A(HasSystemMessage):
    # Some model fields

HasSystemMessage.objects.filter(a__contains=[some elements])

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Вы можете использовать %(class)s или %(app_label)s

class HasSystemMessage(models.Model):
    class Meta:
        abstract = True

    messages = models.ManyToManyField(SystemMessage, related_name=%(app_label)s_%(class)s_related)

Из документов Django

Будьте осторожны с related_name и related_query_name¶ Если вы используете related_name или related_query_name для ForeignKey или ManyToManyField, Вы всегда должны указывать уникальное обратное имя и имя запроса для поле. Это обычно вызывает проблемы в абстрактных базовых классах, так как поля этого класса включены в каждый из дочерних классы, с точно такими же значениями для атрибутов (включая related_name и related_query_name) каждый раз.

Чтобы обойти эту проблему, когда вы используете related_name или related_query_name в абстрактном базовом классе (только), часть значения должен содержать «% (app_label) s» и «% (class) s».

'% (class) s' заменяется на имя в нижнем регистре дочернего класса что поле используется в. "% (app_label) s" заменяется на имя в нижнем регистре приложения, в котором содержится дочерний класс. каждый имя установленного приложения должно быть уникальным, а имена классов модели в каждом приложении также должно быть уникальным, поэтому полученное имя будет в конечном итоге быть другим.

Ссылка: https://docs.djangoproject.com/en/2.0/topics/db/models/#be-careful-with-related-name-and-related-query-name

0 голосов
/ 05 сентября 2018

Вам просто нужно вставить строку в этот атрибут, которая задает имя обратной связи из SystemMessage. Также читайте в Django Docs

Попробуйте это:

class HasSystemMessage(models.Model):
class Meta:
    abstract = True

messages = models.ManyToManyField(SystemMessage, related_name='system_message')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...