有没有一种有效的方法来递归查询 Django 模型中的多对多字段?

huangapple go评论90阅读模式
英文:

Is there an efficient way to recursively query a Django model manytomany field?

问题

以下是代码的翻译部分:

class Role(models.Model):
    title = models.CharField(max_length=255, verbose_name='Role Title')
    parents = models.ManyToManyField("self", symmetrical=False)
    skills = models.ManyToManyField(Skill)

关于如何高效地获取与这个 "Role" 对象及其父对象相关的所有 "Skill" 对象,可以采用以下方法:

例如,如果问题中的 "Role" 对象是 'Manager',它将继承来自 'Team Leader' 的技能,而 'Team Leader' 又继承来自 'Team Member' 等等。

英文:

Given this model:

class Role(models.Model):
    title = models.CharField(max_length=255, verbose_name='Role Title')
    parents = models.ManyToManyField("self", symmetrical=False)
    skills = models.ManyToManyField(Skill)

What is the most efficient way to get a list of all the 'Skill' objects related to this 'Role' object, and its parents, recursively?

For example, if the Role object in question is 'Manager', it will inherit skills from 'Team Leader', which inherits skills from 'Team Member' etc.

答案1

得分: 1

我认为你需要一次获取它们一个批次。

    skills = list(roll.skills.all())
    for parent in parents:
        skills.extend(list(parent.skills.all())

或者,如果你只想要唯一的技能集,可以使用set代替list

当需要时,你当然可以将这段代码编写成一个模型管理器方法,以便轻松访问。

英文:

I think you'd have to get them one lot at a time.

    skills = list(roll.skills.all())
    for parent in parents:
        skills.extend(list(parent.skills.all())

Or set instead of list if you just want a unique set of skills.

You could of course write this as a modelmanager method, so it was easily available when needed.

答案2

得分: 1

尝试使用一个辅助函数,如下所示:

class Role(models.Model):
    title = models.CharField(max_length=255, verbose_name='角色标题')
    parents = models.ManyToManyField("self", symmetrical=False)
    skills = models.ManyToManyField(Skill)

    def get_all_skills(self):
        """
        递归地检索角色及其父级的所有技能
        """
        all_skills = set(self.skills.all())
        for parent in self.parents.all():
            all_skills.update(parent.get_all_skills())
        return all_skills

然后使用这个方法来获取角色及其父级的所有技能:

role = Role.objects.get(title='Manager')
all_skills = role.get_all_skills()

这个解决方案避免了多次迭代父级的需要,使其更加高效。它还提供了一个方便的方法,可以在需要的地方调用,以获取角色及其父级的所有技能。

英文:

Try to use a helper function, like the following:

class Role(models.Model):
    title = models.CharField(max_length=255, verbose_name='Role Title')
    parents = models.ManyToManyField("self", symmetrical=False)
    skills = models.ManyToManyField(Skill)

    def get_all_skills(self):
        """
        Recursively retrieve all skills of the role and its parents
        """
        all_skills = set(self.skills.all())
        for parent in self.parents.all():
            all_skills.update(parent.get_all_skills())
        return all_skills

Then use this method to get all the skills of a role and its parents:

role = Role.objects.get(title='Manager')
all_skills = role.get_all_skills()

This solution avoids the need to iterate over the parents multiple times, making it more efficient. It also provides a convenient method to get all the skills of a role and its parents, which can be called wherever needed.

huangapple
  • 本文由 发表于 2023年3月10日 00:39:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75687546.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定