【问题标题】:Django access manytomany field from related_name in a viewDjango从视图中的related_name访问manytomany字段
【发布时间】:2022-01-23 08:07:59
【问题描述】:

我有一个我认为很简单的问题,但我正在努力找出它是如何工作的。我知道外键的相关名称是如何工作的,但是对于很多领域,这似乎让我很头疼。

我这里有两个 3 模型。如下所示的用户、团队成员和团队模型。

用户模型是内置的 django 模型。

#TeamMember Model
class TeamMember(models.Model):
    member = models.ForeignKey(User, on_delete=models.SET(get_default_team_member), verbose_name='Member Name', related_name="team_members")
    ...

#Team Model
class Team(models.Model):
    name = models.CharField(max_length=50)
    manager = models.ForeignKey(TeamMember, on_delete=models.SET_NULL, related_name="managers", null=True, blank=True)
    team_lead = models.ForeignKey(TeamMember, on_delete=models.SET_NULL, related_name="tls", null=True, blank=True)
    tps = models.ForeignKey(TeamMember, on_delete=models.SET_NULL, related_name="tps",  null=True, blank=True)
    members = models.ManyToManyField(TeamMember, blank=True, related_name="members")
    ...

现在在一个视图中,我想访问特定的用户团队。我想我可以通过这样做来做到这一点:

member = TeamMember.objects.get(pk=1)
member_team = member.members.name

但是,如果我打印member_name,它什么也不会打印。如果我尝试访问该模型上的任何其他字段,例如member.members.team_lead.first_name,它将无法找到team_lead 字段。我知道这有一个.all() 属性,但我认为它是通过成员字段绑定到团队对象的。因此,如果该成员与团队匹配,它将给我团队。所以我认为如果同一个成员与多个团队相关联(这是可能的)可能是一个问题,所以我厌倦了这样的member.members.all().first().name 并且我收到一个错误,指出它无法从 NoneType 获取名称。

有没有一种简单的方法可以从这样的关系中获取团队名称,还是我最好只与用户进行团队查询?

谢谢, jAC

【问题讨论】:

    标签: django django-models django-views django-related-manager


    【解决方案1】:

    首先,我想指出您没有以正确的方式使用related_name(和related_query_name 参数)。我认为this SO post 将帮助您更好地理解这个概念。

    所以,我将更改 Team 模型中的related_name(和related_query_name)值,如下所示,

    class Team(models.Model):
        name = models.CharField(max_length=50)
        manager = models.ForeignKey(
            TeamMember,
            on_delete=models.SET_NULL,
            related_name="teams",
            related_query_name="team",
            null=True,
            blank=True,
        )
        team_lead = models.ForeignKey(
            TeamMember,
            on_delete=models.SET_NULL,
            related_name="teams",
            related_query_name="team",
            null=True,
            blank=True,
        )
        tps = models.ForeignKey(
            TeamMember,
            on_delete=models.SET_NULL,
            related_name="teams",
            related_query_name="team",
            null=True,
            blank=True,
        )
        members = models.ManyToManyField(
            TeamMember, blank=True, related_name="teams", related_query_name="team"
        )
        ...

    现在在一个视图中,我想访问特定用户的团队。

    由于TeamTeamMember 模型通过ManyToManyField 连接,您可能有“零个或多个” Teams 与单个TeamMember

    因此,以下查询将为您提供与特定 TeamMemeber 关联的所有团队

    team_member = TeamMember.objects.get(pk=1)
    all_teams = team_member.teams.all()
    

    您还可以将 QuerySet 迭代为,

    team_member = TeamMember.objects.get(pk=1)
    for team in team_member.teams.all():
        print(team.name)
    

    【讨论】:

    • 嘿@JPG 感谢您提供额外的详细信息。我不需要做那么多,那个帖子很有帮助!非常感谢!
    • 其实我不认为我使用了related_name 错误。如果我将其更改为您的建议,则无法说我不能使用相同的相关名称...但是,您的其余建议帮助我解决了问题。
    • 您以正确的方式使用(以编程方式),但从逻辑上讲,它是错误的。
    • 不确定它是怎么错的,因为你上面的例子不能以编程方式工作。你能详细说明吗?只是好奇我应该做什么而不是那个。
    【解决方案2】:

    如果有人想知道我根据 JPG 的建议做了什么,那就是 for 循环选项

    team_member = TeamMember.objects.get(pk=1)
    teams = [t.name for t in team_member.members.all()]
    

    我个人并不关心我得到哪个团队,因为在这种情况下我的需要只是让一个团队通过,即使它没有。所以我只使用team = team[0] if teams.count() > 0 else "No team"

    【讨论】:

      猜你喜欢
      • 2014-07-10
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 2018-06-09
      • 2011-04-28
      • 1970-01-01
      • 2018-04-26
      相关资源
      最近更新 更多