简体   繁体   English

嵌套序列化器Django Rest Framework

[英]Nested Serializers Django Rest Framework

I have two models Stage and Application. 我有两个模型Stage和Application。 I am getting an error like this: 我收到这样的错误:

Exception Type: ImportError 异常类型:ImportError

Exception Value: cannot import name ApplicationSerializer 异常值:无法导入名称ApplicationSerializer

Exception Location: /Users/jojjen/workspace/indusaction/vms/stages/serializers.py in , line 7 异常位置:第7行中的/Users/jojjen/workspace/indusaction/vms/stages/serializers.py

I am guessing that this error is due to cyclic imports in the serializers. 我猜想这个错误是由于序列化程序中的循环导入引起的。 But I have no clue how to resolve this. 但是我不知道如何解决这个问题。

If I remove the ApplicationSerializer import from StageSerializer , it works. 如果我从StageSerializer中删除ApplicationSerializer导入,则可以正常工作。 But I need to access certain properties of stage's application in the template that I am building. 但是我需要在要构建的模板中访问舞台应用程序的某些属性。

Following is the code: 以下是代码:

stages/models.py: 阶段/ models.py:

from django.db import models

from core.models import TimeStampedModel

from applications.models import Application

from authentication.models import Account


class Stage(TimeStampedModel):
    name = models.CharField(max_length=20)

    application = models.ForeignKey(Application, null=True, related_name='stages')

    assignee = models.ForeignKey(Account, null=True)

    def __unicode__(self):
        return self.name

applications/models.py: 应用程序/ models.py:

from django.db import models

from core.models import TimeStampedModel

from organizations.models import Organization
from authentication.models import Account


class Application(TimeStampedModel):
    title = models.CharField(max_length=30, unique=True)
    details = models.TextField()
    archived = models.BooleanField(default=False)

    organization = models.ForeignKey(Organization, null=True)

    users = models.ManyToManyField(Account, related_name='applications')

    creator = models.ForeignKey(Account, null=True)

    def __unicode__(self):
        return self.title

stages/serializers.py 阶段/ serializers.py

from rest_framework import serializers

from stages.models import Stage

from authentication.serializers import AccountSerializer

from applications.serializers import ApplicationSerializer


class StageSerializer(serializers.ModelSerializer):
    assignee = AccountSerializer(read_only=True, required=False)
    application = ApplicationSerializer(read_only=True, required=False)

    class Meta:
        model = Stage
        fields = ('id', 'name', 'assignee', 'created_at', 'updated_at',
                  'application',)
        read_only_fields = ('created_at', 'updated_at', 'assignee',
                            'application',)

        def get_validation_exclusions(self, *args, **kwargs):
            exclusions = super(StageSerializer,
                               self).get_validation_exclusions()

            return exclusions + ['assignee', 'application']

applications/serializers.py: 应用程序/ serializers.py:

from rest_framework import serializers

from applications.models import Application

from organizations.serializers import OrganizationSerializer
from authentication.serializers import AccountSerializer
from stages.serializers import StageSerializer
from applicants.serializers import ApplicantSerializer


class ApplicationSerializer(serializers.ModelSerializer):
    organization = OrganizationSerializer(read_only=True, required=False)
    creator = AccountSerializer(read_only=True, required=False)
    users = AccountSerializer(read_only=True, required=False, many=True)
    stages = StageSerializer(read_only=True, required=False, many=True)
    applicant_set = ApplicantSerializer(read_only=True, required=False, many=True)

    class Meta:
        model = Application

        fields = ('id', 'title', 'details', 'organization', 'stages',
                  'creator', 'archived', 'users', 'applicant_set')
        read_only_fields = ('id', 'organization', 'users', 'applicant_set',
                            'created_at', 'updated_at', 'stages')

    def get_validation_exclusions(self, *args, **kwargs):
        exclusions = super(ApplicatiionSerializer,
                           self).get_validation_exclusions()

        return exclusions + ['organization', 'users', 'creator', 'stage_set', 'applicant_set']

This code is not valid, you cannot have cyclic imports and dependencies. 此代码无效,您不能具有循环导入和依赖关系。 This is not even true for Django Rest Framework by Python in general. 通常,对于Python的Django Rest Framework来说,甚至都不是这样。 You have to change your design to remove this cyclic dependency. 您必须更改设计以删除此循环依赖性。

A circular dependency in any language, is an infinite recursion. 任何语言中的循环依赖项都是无限递归。

Look at this library - https://github.com/heywbj/django-rest-framework-recursive/tree/master/rest_framework_recursive . 看一下这个库-https: //github.com/heywbj/django-rest-framework-recursive/tree/master/rest_framework_recursive This can be used to emulate circular dependency like in a tree or linked list. 这可以用于模拟循环依赖,例如在树或链表中。

But I would still suggest you to re consider your design. 但是我仍然建议您重新考虑您的设计。 Read why circular dependency is a sign of poor design. 了解为什么循环依赖是不良设计的标志。 If that is not possible, put interdependent components into the same module. 如果不可能,则将相互依赖的组件放入同一模块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM