django - 序列化相关字段的问题(许多等)......寻找良好实践
问题描述
我有一些问题要理解使用 django-rest-framework 序列化数据的正确方法,例如使用来自相关模型的数据。
让我稍微解释一下我的情况:
我有一个组织模型,它与对每个组织进行分类的子主题模型具有多对多关系。此外,每个子主题都属于一般主题。
此外,还有一个 OrgaDataSet 模型可以将每个组织的爬网数据保存在 PostgreSQL JSONField 中。OrgaDataSet 模型中的字段“类型”应该给我一种灵活性,以便在进一步的阶段对抓取的数据进行分类。
# models.py
class Topic(models.Model):
name = models.CharField(max_length=200, unique=True)
class Subtopic(models.Model):
name = models.CharField(max_length=100, unique=True)
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
class Organization(models.Model):
name = models.CharField(max_length=300, unique=True)
description = models.TextField(blank=True, null=True)
subtopics = models.ManyToManyField(Subtopic)
class OrgaDataSet(models.Model):
data_set_types = (
('ADDRESS', 'address'),
('PERSON', 'person'),
('DIVISION', 'division'),
)
organization = models.ForeignKey(Organization, on_delete=models.CASCADE)
type = models.CharField(max_length=20, choices=data_set_types)
crawled_data = JSONField(verbose_name='Data set')
但是让我们提出我的问题/问题:
1.如何使用最小化的数据库请求序列化相关数据并获得自定义的序列化字段,例如:
"topics_list": [
{
"topic_name": "Medical science",
"subtopics": [
"Dental products",
"Hygiene"
]
},
{
"topic_name": "Biotechnology",
"subtopics": [
"Microbiology"
]
}
],
我尝试了不同的方法:其中一个自定义模型管理器添加了一个方法“get_topics_list”,但是我坚持使用正确的方法来查询“prefetch_related”和“select_related”......但这甚至是最丰富的方式吗?
我还尝试在序列化程序本身中设置一个 serializedMethodField 。但是我问自己在 view.py 还是在 serializers.py 中进行相关查询的最佳位置是什么?
- 我的第二个问题涉及 OrgaDataSet 模型。我绝对不确定如何以及在何处放置查询,每种“类型”一个。我应该在自定义模型管理器中为每种类型执行特定方法,例如“get_type_address”吗?
我将不胜感激您的想法和任何提示,以进一步了解 django-framework 的使用情况。
非常感谢,迈克
解决方案
问题 1)这是典型的类别/子类别问题。我建议查看以下 django 包:https ://github.com/django-mptt/django-mptt
它将主题/子主题存储在一个表(树结构)中,使查询高效,您可以轻松高效地生成所需的输出
问题 2)这取决于您希望如何显示数据。每种类型都有一个端点吗?
如果每种类型都有一个端点,则可以执行如下视图:
class OrgaDataSetListView(generics.ListAPIView):
type = None
serializer_class =<your serializer>
def get_queryset(self):
return OrgaDataSet.objects.filter(type=self.type)
并在 url 中像这样使用它:
urlpatterns = [
path('orgadata/address', OrgaDataSetListView.as_view(type='ADDRESS')),
path('orgadata/person', OrgaDataSetListView.as_view(type='PERSON')),
]