如何在模型X与模型Y有关系的情况下,从模型X中的模型X序列化外键?

时间:2019-08-10 17:14:26

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

我需要在“注册”视图中序列化“合同”视图。

我了解在与合同模型相关的注册模型中是否存在外键的情况下,但在这种情况下,合同模型与注册模型之间存在某种关系。

我需要在更大的项目中执行此操作,这只是一个简单的样板。 基本上,我希望我的输出是这样:

[
    {
        "id": 1,
        "client": "John Doe",
        "contract": {
            "id": 1,
            "client": "John Doe",
            "name": "New Identity",
            "registration": 1
        }
    },
    {
        "id": 2,
        "client": "Jane Doe",
        "contract": {
            "id": 2,
            "client": "Jane Doe",
            "name": "Identity theft",
            "registration": 2
        }
    }
]

型号:

class Client(models.Model):
    name = models.CharField(max_length=250)
    address = models.CharField(max_length=250)
    email = models.EmailField()

class Registration(models.Model):
    client = models.ForeignKey(Client, on_delete=models.CASCADE)

class Contract(models.Model):
    name = models.CharField(max_length=150)
    client = models.ForeignKey(Client, on_delete=models.CASCADE)
    registration = models.ForeignKey(Registration, on_delete=models.CASCADE)

视图集:

class ClientViewSet(viewsets.ModelViewSet):
    queryset = Client.objects.all()
    serializer_class = ClientSerializer


class RegistrationViewSet(viewsets.ModelViewSet):
    queryset = Registration.objects.all()
    queryset = queryset.select_related("client")
    serializer_class = RegistrationSerializer


class ContractViewSet(viewsets.ModelViewSet):
    queryset = Contract.objects.all()
    queryset = queryset.select_related("registration").prefetch_related(
        "client"
    )
    serializer_class = ContractSerializer

序列化器:

class ClientSerializer(serializers.ModelSerializer):
    class Meta:
        model = Client
        fields = "__all__"


class ContractSerializer(serializers.ModelSerializer):
    client = NameSerializer()

    class Meta:
        model = Contract
        fields = "__all__"


class RegistrationSerializer(serializers.ModelSerializer):
    client = NameSerializer()

    class Meta:
        model = Registration
        fields = "__all__"

1 个答案:

答案 0 :(得分:0)

您仍可以使用register_obj.contract_set.all()查询合同,这将返回所有具有外键指向所选register_obj的行。

您的序列化器应如下所示:

class RegistrationSerializer(serializers.ModelSerializer):
    client = NameSerializer()
    contracts = SerializerMethodField()

    class Meta:
        model = Registration
        fields = "__all__"

    def get_contracts(self, obj):
        # if you need all the contracts in a list:
        return ContractSerializer(obj.contract_set.all(), many=True).data

        # or if you just need the first one:
        return ContractSerializer(obj.contract_set.first()).data
        # you can also filter the query