gpt4 book ai didi

django-rest-framework - Django REST 框架 : passing context to a nested serializer

转载 作者:行者123 更新时间:2023-12-05 07:49:18 24 4
gpt4 key购买 nike

我有一对父子模型/序列化器/ View 集 - 工具和工具输入:

模型.py:

class Tool(models.Model):
id = models.CharField(max_length=10000, primary_key=True, default=uuid.uuid4, editable=False)
base_command = jsonfield.JSONField(verbose_name="baseCommand")

class ToolInput(models.Model):
tool = models.ForeignKey(Tool, related_name="inputs", on_delete=models.CASCADE)
id = models.CharField(max_length=10000, primary_key=True)
label = models.CharField(max_length=10000, null=True, blank=True)
description = models.CharField(max_length=10000, null=True, blank=True)
type = jsonfield.JSONField()

serializers.py

class ToolSerializer(WritableNestedModelSerializerMixin,
serializers.HyperlinkedModelSerializer):
id = serializers.CharField()
inputs = ToolInputSerializer(many=True)
baseCommand = serializers.JSONField(source="base_command")

class Meta:
model = Tool
fields = ('id', 'inputs', 'baseCommand')

class ToolInputSerializer(WritableNestedModelSerializerMixin,
serializers.HyperlinkedModelSerializer):
class Meta:
model = ToolInput
fields = ('id', 'label', 'description', 'type')

views.py:

class ToolViewSet(viewsets.ModelViewSet):
queryset = Tool.objects.all()
lookup_field = 'id'
serializer_class = ToolSerializer

class ToolInputViewSet(viewsets.ModelViewSet):
lookup_field = 'id'
serializer_class = ToolInputSerializer

def get_queryset(self):
tool_id = self.kwargs['tool_id']
return ToolInput.objects.filter(tool_id=tool_id)

def get_serializer_context(self):
context = super(ToolInputViewSet, self).get_serializer_context()
context["tool"] = Tool.objects.get(id=self.kwargs['tool_id'])
return context

如您所见,我使用 ToolInputSerializer 作为 ToolInputViewSet 的独立序列化程序和 ToolViewSet 中的嵌套序列化程序。

ToolInputSerializer 用作 ToolViewSet 中的嵌套序列化程序时,它会以某种方式自动接收 tool 参数的值并将其分配给 ToolInput 模型的 tool 字段(顺便说一句,我觉得从架构的角度来看这是一个完全错误的行为 - tool 上没有这样的字段 ToolInputSerializer 并且 DRF 填充了相应模型的字段 - 它应该用 Field Does Not Exist 错误 IMO 和至少需要一个只写字段 tool 在序列化器上)。

但是当我在 ToolInputViewSet 中将它用作独立的序列化程序时,我想将 ToolInput 模型的 tool 字段的值分配给 Tool 实例,由 tool_id url 参数确定,由 kwargs 中的 ToolInputViewSet 接收。

我试图通过序列化程序上下文传递该字段的值,覆盖 ToolInputViewSet.get_serializer_context() 方法,但它不起作用。如何正确地做到这一点?


旁注:我已经厌倦了 DRF 上下文处理的困惑、不一致、不统一的自动化,它穿透了模型-序列化器-字段- View 架构的各个层。它确实需要更加明确和可定制。

最佳答案

至于上下文,我仍然不知道如何让它发挥作用。

至于嵌套序列化器的工作方式,这是我的缺点:如您所见,我从我的自定义 WritableNestedModelSerializerMixin 继承了所有 ViewSet,我在其中覆盖了 create()update() 方法来处理嵌套数据结构,所以这是我的修补。

因此,作为解决方法,我创建了一个单独的 StandaldonToolInputSerializer 并修改了 ToolInputViewSet,将缺少的 tool 字段添加到序列化程序并自动修补 request.data 与工具引用:

serializers.py

class StandaloneToolInputSerializer(serializers.HyperlinkedModelSerializer):
tool = serializers.PrimaryKeyRelatedField(
write_only=True,
many=False,
queryset=Tool.objects.all()
)
inputBinding = serializers.JSONField(source="input_binding")

class Meta:
model = ToolInput
fields = ('id', 'tool', 'label', 'description', 'type', 'inputBinding')

views.py

class ToolInputViewSet(viewsets.ModelViewSet):
'''
Describes a Tool input.
'''
lookup_field = 'id'
serializer_class = StandaloneToolInputSerializer

def get_queryset(self):
tool_id = self.kwargs['tool_id']
return ToolInput.objects.filter(tool_id=tool_id)

def create(self, request, *args, **kwargs):
request.data["tool"] = self.kwargs['tool_id']
return super(ToolInputViewSet, self).create(request, *args, **kwargs)

def update(self, request, *args, **kwargs):
request.data["tool"] = self.kwargs['tool_id']
return super(ToolInputViewSet, self).update(request, *args, **kwargs)

关于django-rest-framework - Django REST 框架 : passing context to a nested serializer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37483831/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com