将相关字段序列化的问题(许多其他)……寻找良好实践

时间:2018-09-09 10:37:13

标签: django serialization django-models django-rest-framework django-queryset

我有一些问题,无法理解使用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中进行相关查询的最佳位置是什么?

  1. 我的第二个问题涉及OrgaDataSet模型。我绝对不确定如何以及在哪里放置查询,每个“类型”都放置一个。是否应该在自定义模型管理器中为每种类型(例如“ get_type_address”)执行特定的方法?

我将很感谢您的想法,以及任何更多了解django框架用法的提示。

非常感谢, 迈克

1 个答案:

答案 0 :(得分:0)

问题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')),
]