DRF(Django)层次结构

2024-04-25 21:32:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要创建一个层次结构,并添加了模型列表,如下所示:

class Category(models.Model):
    name = models.CharField(max_length=255)


class Form(models.Model):
    parent = models.ForeignKey('Category', related_name='category', on_delete=models.CASCADE)
    name = models.CharField(max_length=255)


class Type(models.Model):
    parent = models.ForeignKey('Form', related_name='form', on_delete=models.CASCADE)
    name = models.CharField(max_length=255)


class Point(models.Model):
    parent = models.ForeignKey('Point', related_name='point', on_delete=models.CASCADE)
    name = models.CharField(max_length=255)

所以,请建议如何处理这个结构。我必须实施两个案例:

  1. 我需要从'point'表中获取一条记录,它应该返回所有上层结构:point Type Form Category
  2. 我还需要从具有完整层次结构(内部结构,在每个记录下)的类别中获取所有记录。你知道吗

那么,实施这一目标的最佳方式或手段是什么?你知道吗


Tags: nameformmodelonmodelsdeletelengthmax
1条回答
网友
1楼 · 发布于 2024-04-25 21:32:13

老实说,每个模型中都有类似的字段(nameparent)。与其这样设计,不如使用相同的模型,例如:

class Node(models.Model):
    CATEGORY = 'C'
    FORM = 'F'
    TYPE = 'T'
    POINT = 'P'
    CHOICES = (
        (CATEGORY, 'CATEGORY'),
        (FORM, 'FORM'),
        (TYPE, 'TYPE'),
        (POINT, 'POINT'),
    )
    node_type = models.CharField(
        max_length=2,
        choices=CHOICES,
        default=CATEGORY
    parent = models.ForeignKey('self', null=True, default=None, related_name='children')
    name = models.CharField(max_length=255, null=True, default=None)

现在,如果你想从点到类型,你可以这样做:

def get_children(node):
   qset = Node.objects.filter(pk=node.pk)
   for child in node.children.all():
      qset.union(get_children(child)) # using recursion
   return qset

def get_parents(node):
  qset = Node.objects.filter(pk=node.pk)
  while(node.parent):
     qset.union(Node.objects.filter(pk=node.parent.pk))
     node = node.parent
  return qset

更新

假设您有一些额外的数据可能与某个点的模型相关,您可以与该节点和另一个包含该额外数据的模型建立OneToOne关系。例如:

class ExtraPoint(models.Model):
    point = models.OneToOneField(Node, related_name='point')
    data = models.CharField(max_length=255)

然后您可以像这样访问这些数据:

for node in Node.objects.all():
    if node.point:
        print(node.point.data)

相关问题 更多 >