如何访问“多对多”对象以获取另一个模型属性?

时间:2019-06-27 08:11:05

标签: python django

我正在为Django仪表板编写工具提示,因此其中一种情况表示,当用户尚未连接其Github帐户时,存储库链接将被禁用。我已经解决了问题,但是我没有意识到它仅适用于存储库的所有者,因此,如果我添加其他人作为协作者,则该链接将对他们有效,因为ofc,它们不是所有者。

models.py

class Project(models.Model):
    owner = models.ForeignKey(
        TeamMember,
        related_name="github_repos",
        blank=True,
        null=True,
        on_delete=models.SET_NULL,
    )

    members = models.ManyToManyField(
        TeamMember,
        related_name="new_projects",
        blank=True,
        through=ProjectMember,
    )

class TeamMember(models.Model):
    class Meta:
        unique_together = ("team", "user_id")

    django_user = models.OneToOneField(
        settings.AUTH_USER_MODEL,
        related_name="team_member",
        null=True,
        on_delete=models.SET_NULL,
    )
    team = models.ForeignKey(
        Team, related_name="members", on_delete=models.SET_NULL, null=True
    )
    github_username = models.CharField(max_length=100, blank=True)

所以基本上我解决问题的方式是这样的:

    def html_message(self):
        pattern = re.compile("Github Repository", re.IGNORECASE)

        if self.project.owner.has_connected_github:
            git_connection = self.project.owner.django_user.socialaccount_set.filter(
                provider="github"
            ).first()
            if git_connection:
                html_message = pattern.sub(
                    f"<a href='{self.project.html_url}'>Github Repository</a>", self.message
                )
            else:
                html_message = pattern.sub(
                    f"<a href='#' data-toggle='tooltip' title='Connect your Github account to access repository.'>Github Repository</a>", self.message
                ) 

那行得通,但是正如我之前说过的,仅对于应用程序所有者,我需要知道如何访问members而不是owner,因为您可以看到很多许多领域。

任何想法我该如何访问?我看到了类似的问题,但我并不完全理解它们。

2 个答案:

答案 0 :(得分:1)

由于members是一个m2m字段,因此您可以通过TeamMember访问project.members.all()查询集。与TeamMember.objects.filter(project=self.project)

基本相同

为了显示特定成员的正确消息,您应该可以通过html_message方法访问该成员。您可能在请求中某处有用户,或已将其附加到该类。这是一个示例:

# Pass the user to the method. Maybe you have it in the request.user somewhere near
def html_message(self, user): # or pass a request and then get request.user
    pattern = re.compile("Github Repository", re.IGNORECASE)

    member = self.project.members.filter(django_user=user)

    # It's not clear what your needs if a member does not exist,
    # so I'm taking a shourtcut
    if not member:
        return

    if member.has_connected_github:
        git_connection = user.socialaccount_set.filter(provider="github").first()
        if git_connection:
            html_message = pattern.sub(
                f"<a href='{self.project.html_url}'>Github Repository</a>", self.message
            )
        else:
            html_message = pattern.sub(
                f"<a href='#' data-toggle='tooltip' title='Connect your Github account to access repository.'>Github Repository</a>", self.message
            ) 

答案 1 :(得分:0)

我会以这种方式亲自处理

  1. 获取项目中的所有members

    all_members = self.project.members.all()

  

这将返回一个QuerySet

  1. 遍历all_members QuerySet并应用与owner相同的逻辑

喜欢

for member in all_members:
    if member.has_connected_github:
      .................