Могу ли я объявить два ForeignKey для одной таблицы в одной абстрактной модели Django ORM?
Подскажите, могу ли я объявить два ForeignKey для одной таблицы в одной абстрактной модели? Я могу сделать так:
class TrackableDateModel(models.Model):
"""Abstract model to Track the creation/updated date for a model."""""
create_date = models.DateTimeField(auto_now_add=True, help_text="Creation time", verbose_name="Created", null=True, blank=True)
create_user = models.ForeignKey(User, related_name="create_user", on_delete=models.CASCADE, help_text="Who created", verbose_name="Author", null=True, blank=True)
update_date = models.DateTimeField(auto_now=True, help_text="Time of change", verbose_name="Changed", null=True, blank=True)
class Meta:
abstract = True
class A(TrackableDateModel):
....
class B(TrackableDateModel):
.....
Но не может добавить в TrackableDateModel:
update_user = models.ForeignKey(User, related_name="update_user", on_delete=models.CASCADE, help_text="Who modified", verbose_name="Author of change", null=True, blank=True)
Потому что makemigrations клянется.
ERRORS:
DjModule.A.create_user: (fields.E304) Reverse accessor 'User.create_user' for 'DjModule.A.create_user' clashes with reverse accessor for DjModule.B.create_user'.
HINT: Add or change a related_name argument to the definition for 'DjModule.A.Export4Payment.create_user' or 'DjModule.B.create_user'.
и разбивается...
TLDR: You can do this, but not with a fixed related_name=…
[Django-doc]. You can use %(class)s
and %(app_label)s
to make the related_name=…
items unique, as is discussed in the Be careful with related_name and related_query_name section [Django-doc].
Причина, по которой моделирование в вашем вопросе не будет работать, заключается в том, что related_name
- это имя отношения в reverse, то есть от User
к подклассу (или потомку в общем случае) TrackableDateModel
. Теперь, если это create_user
, что тогда делать some_user.create_user.all()
? Какую модель он должен выбрать?
Вы можете создавать различные отношения, каждое из которых будет иметь свое имя, например:
class TrackableDateModel(models.Model):
'Abstract model to Track the creation/updated date for a model.'
create_date = models.DateTimeField(
auto_now_add=True,
help_text='Creation time',
verbose_name='Created',
null=True,
blank=True,
)
create_user = models.ForeignKey(
User,
related_name='created_%(class)ss',
on_delete=models.CASCADE,
help_text='Who created',
verbose_name='Author',
null=True,
blank=True,
)
update_date = models.DateTimeField(
auto_now=True,
help_text='Time of change',
verbose_name='Changed',
null=True,
blank=True,
)
тогда модель User
будет иметь дополнительные атрибуты .created_as
, .created_bs
и т.д.
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation [Django-doc].