【问题标题】:How can I return nested entity from other database in json response in Django Rest Framework?如何在 Django Rest Framework 的 json 响应中从其他数据库返回嵌套实体?
【发布时间】:2016-11-01 06:40:45
【问题描述】:

我使用 Python、Django 和 DRF。 我有 2 个数据库。 其中一个包含名为“documents”的表(字段:id、name、document_type_id),第二个数据库包含名为“document_type”的表(字段:id、name、description)。 表“document”中的字段“document_type_id”已填充表“document_type”中的值。 正如 Django 文档所说:“Django 目前不支持外键或跨多个数据库的多对多关系。” 问题:在 GET 请求中序列化实体 'document' 时,如何显示嵌套实体 'document_type'?

Example entity 'document':
 {
  "id": 1,
  "name": "document_name",
  "document_type": {
    "id": 25,
    "name": "passport",
    "description": "identity document"
  }


Example list of 'documents':
{
  "id": 1,
  "name": "document_name",
  "document_type": {
    "id": 25,
    "name": "passport",
    "description": "identity document"
  },
{
  "id": 2,
  "name": "document_name2",
  "document_type": {
    "id": 24,
    "name": "reference",
    "description": "reference document"
  }

模型的代码(models.py)

class Document(models.Model):
    name = models.TextField()
    document_type_id = models.BigIntegerField()

    class Meta:
        db_table = "documents"
        managed = False

class DocumentType(models.Model):
    name = models.TextField()
    description = models.TextField()

    class Meta:
        db_table = "document_type"
        managed = False

序列化器的代码(serializer.py)

class DocumentSerializer(serializers.ModelSerializer):

    class Meta:
        model = Document
        fields = ('id', 'name', 'document_type')


class DocumentTypeSerializer(serializers.ModelSerializer):

    class Meta:
        model = DocumentType
        fields = ('id', 'name', 'description')

视图的代码(views.py)

class DocumentDetailView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Document.objects.all()
    serializer_class = DocumentSerializer


class DocumentListCreateView(generics.ListCreateAPIView):
    queryset = Document.objects.all()
    serializer_class = DocumentSerializer


class DocumentTypeView(generics.RetrieveUpdateDestroyAPIView):
    queryset = DocumentType.objects.all()
    serializer_class = DocumentTypeSerializer

class DocumentTypeListCreateView(generics.ListCreateAPIView):
    queryset = DocumentType.objects.all()
    serializer_class = DocumentTypeSerializer

【问题讨论】:

  • 这个是单值还是列表?
  • 可以是单值也可以是列表。
  • 您能否添加您的视图代码,以便我可以在您的代码上下文中向您展示示例
  • 我在问题中添加了代码

标签: django python-3.x django-rest-framework


【解决方案1】:

Django 没有任何东西可以帮助您实现这一目标。所以你必须手动缝合所有东西

将嵌套序列化程序DocumentTypeSerializer 添加到DocumentSerializer。并在DocumentSerializer 上更改to_representation,它是ListSerialzer

class DocumentTypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = DocumentType
        fields = ('id', 'name', 'description')

class DocumentListSerialzer(serializers.ListSerializer):
    def to_representation(self, data):
        _qs = data.all() if isinstance(data, models.Manager) else data
        dt_mapping = {dt.id: dt for dt in DocumentType.objects.all()}
        documents = []
        for d in _qs:
            d.document_type = dt_mapping[d.document_type_id]
            documents.append(d)
        return documents

class DocumentSerializer(serializers.ModelSerializer):
    document_type = DocumentTypeSerializer()

    class Meta:
        model = Document
        fields = ('id', 'name', 'document_type')
        list_serializer_class = DocumentListSerialzer

    def to_representation(self, obj):
        obj.document_type = DocumentType.objects.get(id=obj.document_type_id)
        return obj

【讨论】:

    猜你喜欢
    • 2020-12-30
    • 2018-03-24
    • 2017-04-08
    • 2013-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-23
    相关资源
    最近更新 更多