django - 如何在模型 Y 中序列化模型 X 的外键,其中模型 X 与模型 Y 有关系?
问题描述
我需要在我的注册视图中序列化我的合同视图。
如果注册模型中有与合同模型相关的外键,我知道该怎么做,但在这种情况下,合同模型与注册模型之间存在关系。
我需要在一个更大的项目中这样做,这只是一个简单的样板。基本上,我希望我的输出是这样的:
[
{
"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__"
解决方案
您仍然可以使用以下方式查询合约:register_obj.contract_set.all()
这将返回所有外键指向 selected 的行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
推荐阅读
- java - 如何使用 Selenium 获取元素标签的请求
- html - Soundcloud iframe 实现到 bootstrap4 问题
- sorbet - 关于冰糕设置的问题:如何消除步骤 4 中的错误
- ruby-on-rails - 在 Rails ActiveRecord 中按条件使用“includes”,没有外键
- angular - Angular 项目不会重定向到 index.html
- spring - Spring MVC 为返回视图的服务层编写单元测试
- r - 如何评估 R 中数据表中布尔列函数的代码?
- matlab - MATLAB:许多矩阵求逆速度更快
- java - 基于事件时间的窗口不触发
- nestjs - 无法运行测试,因为 Nest 找不到模块