python - DRF(Django)层次结构
问题描述
我需要创建一个层次结构,并添加了模型列表,如下所示:
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)
所以,请告知如何处理这种结构。我必须实施两种情况:
- 我需要从“点”表中获取记录,它应该返回所有上层层次结构:Point-Type-Form-Category
- 而且我还需要从具有完整层次结构(内部结构,在每条记录下)的类别中获取所有记录。
那么,实施它的最佳方式或工具是什么?
解决方案
老实说,每个模型(name
和parent
)中都有相似的字段。与其这样设计,不如用同一个模型,比如这样:
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)
推荐阅读
- python - 通过 python 运行 shell 命令来连接 Windows 机器中的多个 CSV 文件
- vue.js - 将图表从 vue-chartjs 转换为 PDF
- php - 在 MODX 中使用 MIGX 配置列表创建动态更新的项目列表
- docker - 如何在 Artifactory (7.11) 中设置匿名 docker 镜像
- stripe-payments - 为不同的计划划出不同的货币?
- python - 如何将 pyinstaller 添加到 PATH?
- python - 根据自定义分隔符反转字符串
- r - R相当于熊猫信息(null_counts = True)?
- sql - 我如何得到结果?
- java - ExoPlayer 没有从特定位置开始视频(android studio)