【问题标题】:Model hierarchy in Django [closed]Django中的模型层次结构[关闭]
【发布时间】:2020-11-13 03:37:18
【问题描述】:

抱歉,文字太长了

给出模型:

  1. 用户

  2. 层次结构

    类层次结构(模型):

      owner = OneToOneField(User)
      subordinates = ManyToManyField(User)
    

有用户,可以互相邀请。反过来,受邀者可以接受或拒绝邀请。

假设 Mark 邀请了 Masha、Katya 和 Dima。玛莎接受了马克的邀请,甚至还邀请了科利亚本人。

在一个选项卡上,您需要显示层次结构。

继续这个例子,马克应该有:

1st level: Masha, Katya, Dima
2nd level: Kolya and other guys

1st level for Mark - those whom he invited.
2nd level - those who were invited by people invited by Mark.

等等。

告诉我如何实现它 |熟悉什么才能更接近结果

【问题讨论】:

  • Stackoverflow 不是免费的编码网站。请先自己实施以证明合理的努力,如果遇到问题,请在您的初始实施到位后发布特定问题以获得进一步的帮助。
  • 我总是先自己尝试,然后才寻求帮助。最好的尝试是:main_hier = Hierarchy.objects.filter(pk=id)。 values_list('subordinates', flat=True) level_hier = {} for sub in main_hier: try: hier = Hierarchy.objects.filter(pk=id)。 values_list('subordinates') 除了 Hierarchy.DoesNotExist: hier = {} level_hier[sub] = hier return level_hier
  • @H-Machine,您能否在问题部分而不是 cmets 部分发布您的代码。这样我们就可以审查您的代码并提供一些指导。

标签: python sql django orm


【解决方案1】:

据我了解,您需要的是树,而不是图表。在这种情况下,为了最大限度地减少数据库查询,您需要对层次结构模型进行现代化改造

from django.db import models
from django.conf import settings
from mptt.models import MPTTModel, TreeForeignKey

class Hierarchy(MPTTModel):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    owner = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='subordinates')

    class MPTTMeta:
        parent_attr = 'owner'
        level_attr = 'mptt_level'
        order_insertion_by=['user']

  • 获取您的清单
from django.shortcuts import get_object_or_404
from .models import Hierarchy
# Get owner
owner = get_object_or_404(Hierarchy, pk=owner_id)
# Get tree users from database
users = Hierarchy.objects.filter(tree_id=owner.tree_id, level__gt=owner.level).select_related('user').order_by('level')

# serialize tree
users_list = []           # list levels users  with users   
users_on_level = []       # list of users of the current tree level
tree_level = owner.level  # current tree level

for user in users:
    if user.level > tree_level:
        tree_level += 1
        users_list.append(users_on_level)
        users_on_level = []
    users_on_level.append(user)

# output users
for level, users in enumerate(users_list, 1):
    print(f"{level} - {', '.join(str(user.username) for user in users) }"

【讨论】:

  • 感谢您的详细解释,希望对其他人有所帮助。我没有使用您的解决方案,但它让我思考并想出了自己的解决方案。如果不是你,这可能不会发生。
  • 我想将答案标记为有帮助,但我没有足够的声望/积分
猜你喜欢
  • 2021-04-30
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 2019-12-18
  • 1970-01-01
  • 2013-05-02
  • 2016-05-01
  • 1970-01-01
相关资源
最近更新 更多