如何与 "through" 模型的父模型建立 "related_name" 关系(关于 related_name 继承)
How to create "related_name" relation with parent models of "through" model (about related_name inheritance)
我有 4 个模型,包括一个 M2M“直通”模型,可以有一个索引:
class TargetShape(models.Model):
pass
class Page(models.Model):
target_shapes = models.ManyToManyField(TargetShape, through='PageElement', related_name='pages')
class PageElement(models.Model):
target_shape = models.ForeignKey(TargetShape, related_name='page_elements')
page = models.ForeignKey(Page, related_name='page_elements')
index = models.PositiveIntegerField(verbose_name='Order')
class WorkingSession(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='working_sessions')
我定义了另一个模型 Resolution
,它使我能够 link 所有这些,以便创建以下 related_name
关系:
working_session.resolutions
user.resolutions
target_shape.resolutions
page.resolutions
page_element.resolutions
要让它正常工作,我必须声明:
class Resolution(models.Model):
# relations that would be needed from a DRY perspective:
page_element = models.ForeignKey(PageElement, related_name='resolutions')
working_session = models.ForeignKey(WorkingSession, related_name='resolutions')
# relations I want to exist to use user.resolutions, target_shape.resolutions, page.resolutions:
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='resolutions')
target_shape = models.ForeignKey(TargetShape, related_name='resolutions')
page = models.ForeignKey(Page, related_name='resolutions')
但是,这不是很干。从 DRY 的角度来看,我应该能够将 Resolution
声明为 linking 到 PageElement
和 WorkingSession
,并推断/继承与父模型的关系:
class Resolution(models.Model):
page_element = models.ForeignKey(PageElement, related_name='resolutions')
working_session = models.ForeignKey(WorkingSession, related_name='resolutions')
但在那种情况下,我如何创建以下关系:
user.resolutions
target_shape.resolutions
page.resolutions
不经过:
user.working_sessions.resolutions
target_shape.page_elements.resolutions
page.page_elements.resolutions
我能想到的就是:
要么像我已经做的那样声明所有字段
或在 User、TargetShape 和 Page 模型中声明一个 属性 分别 returns:
Resolution.objects.filter(working_session__user=自己)
Resolution.objects.filter(page_element__target_shape=自己)
Resolution.objects.filter(page_element__page=自己)
那肯定行得通,但这不是很优雅......而且不是很像 Django
有人知道定义这种关系的更像 Django 的方法吗?
我发现了另一种方法:在 User、TargetShape 和 Page 模型中声明一个 属性 returns 一个查询集:
class Resolution(models.Model):
page_element = models.ForeignKey(PageElement, related_name='resolutions')
working_session = models.ForeignKey(WorkingSession, related_name='resolutions')
class PageElement(models.Model):
target_shape = models.ForeignKey(TargetShape, related_name='page_elements')
page = models.ForeignKey(Page, related_name='page_elements')
index = models.PositiveIntegerField(verbose_name='Order')
class WorkingSession(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='working_sessions')
class TargetShape(models.Model):
@property
def resolutions(self):
return Resolution.objects.filter(page_element__target_shape=self)
class Page(models.Model):
@property
def resolutions(self):
return Resolution.objects.filter(page_element__page=self)
target_shapes = models.ManyToManyField(TargetShape, through='PageElement', related_name='pages')
我有 4 个模型,包括一个 M2M“直通”模型,可以有一个索引:
class TargetShape(models.Model):
pass
class Page(models.Model):
target_shapes = models.ManyToManyField(TargetShape, through='PageElement', related_name='pages')
class PageElement(models.Model):
target_shape = models.ForeignKey(TargetShape, related_name='page_elements')
page = models.ForeignKey(Page, related_name='page_elements')
index = models.PositiveIntegerField(verbose_name='Order')
class WorkingSession(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='working_sessions')
我定义了另一个模型 Resolution
,它使我能够 link 所有这些,以便创建以下 related_name
关系:
working_session.resolutions
user.resolutions
target_shape.resolutions
page.resolutions
page_element.resolutions
要让它正常工作,我必须声明:
class Resolution(models.Model):
# relations that would be needed from a DRY perspective:
page_element = models.ForeignKey(PageElement, related_name='resolutions')
working_session = models.ForeignKey(WorkingSession, related_name='resolutions')
# relations I want to exist to use user.resolutions, target_shape.resolutions, page.resolutions:
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='resolutions')
target_shape = models.ForeignKey(TargetShape, related_name='resolutions')
page = models.ForeignKey(Page, related_name='resolutions')
但是,这不是很干。从 DRY 的角度来看,我应该能够将 Resolution
声明为 linking 到 PageElement
和 WorkingSession
,并推断/继承与父模型的关系:
class Resolution(models.Model):
page_element = models.ForeignKey(PageElement, related_name='resolutions')
working_session = models.ForeignKey(WorkingSession, related_name='resolutions')
但在那种情况下,我如何创建以下关系:
user.resolutions
target_shape.resolutions
page.resolutions
不经过:
user.working_sessions.resolutions
target_shape.page_elements.resolutions
page.page_elements.resolutions
我能想到的就是:
要么像我已经做的那样声明所有字段
或在 User、TargetShape 和 Page 模型中声明一个 属性 分别 returns:
Resolution.objects.filter(working_session__user=自己) Resolution.objects.filter(page_element__target_shape=自己) Resolution.objects.filter(page_element__page=自己)
那肯定行得通,但这不是很优雅......而且不是很像 Django
有人知道定义这种关系的更像 Django 的方法吗?
我发现了另一种方法:在 User、TargetShape 和 Page 模型中声明一个 属性 returns 一个查询集:
class Resolution(models.Model):
page_element = models.ForeignKey(PageElement, related_name='resolutions')
working_session = models.ForeignKey(WorkingSession, related_name='resolutions')
class PageElement(models.Model):
target_shape = models.ForeignKey(TargetShape, related_name='page_elements')
page = models.ForeignKey(Page, related_name='page_elements')
index = models.PositiveIntegerField(verbose_name='Order')
class WorkingSession(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='working_sessions')
class TargetShape(models.Model):
@property
def resolutions(self):
return Resolution.objects.filter(page_element__target_shape=self)
class Page(models.Model):
@property
def resolutions(self):
return Resolution.objects.filter(page_element__page=self)
target_shapes = models.ManyToManyField(TargetShape, through='PageElement', related_name='pages')