我可以使用ModelSerializer(DRF)将多个字段移动到CREATE方法中的JSON字段吗?

问题描述 投票:0回答:2

我正在使用Django Rest Framework构建API。主要要求是它应允许在呼叫中灵活地包含额外字段。基于POST调用,我想在Django中创建一个新记录,其中一些字段(名称和数字不同)应添加到JSON字段(lead_request)。

我怀疑是否应该使用ModelSerializer,因为我不知道如何处理应该作为JSON合并到一个字段中的各个字段。在create方法中,我无法将其他字段合并到JSON中,因为它们未经过验证。

class Leads(models.Model):
    campaign_id = models.ForeignKey(Campaigns, on_delete=models.DO_NOTHING)
    lead_email = models.EmailField(null=True, blank=True)
    lead_request = JSONField(default=dict, null=True, blank=True)

class LeadCreateSerializer(serializers.ModelSerializer):
    def get_lead_request(self):
        return {key: value for key, value in self.request.items() if key.startswith('rq_')}

    class Meta:
        model = Leads
        fields = ['campaign_id',
                  'lead_email',
                  'lead_request']

    def create(self, validated_data):
        return Leads.objects.create(**validated_data)

文档主要讨论分配validated_data,但这里不可能。任何指针都是有用的,因为我是一个没有经验的程序员,我看到解决方案的潜力,但不知道从哪里开始。

python-3.x django-rest-framework django-views
2个回答
0
投票

如果我理解正确并且你想通过URL接收参数,这里有一个如何实现你想要的例子:

class LeadViewSet(viewsets.ModelViewSet):

   def create(self, request, *args, **kwargs):
      data = request.data
      lead_request = generate_lead_request(request)
      data['lead_request'] = lead_request
      serializer = self.get_serializer(data=data)
      serializer.is_valid(raise_exception=True)
      ...

generate_lead_request上,您可以解析可能通过request.data(正文)以及request.query_params发送的所有其他字段。


0
投票

如果我理解这个问题正确主要障碍这里是我们不知道JSON的确切lead_request数据格式。我正在考虑这个问题的两种可能的解决方案模型。我不确定它们中的任何一个是否合适。只想分享我的意见。

case 1

让我们假设数据以这种格式传递给LeadCreateSerializer

data = {

    'campaign_id': campaign_id,
    'lead_email': lead_email,
    'lead_request': { 
         # lead_request
     }

}

然后这很容易,正常模型序列化器应该能够做到这一点。如果数据格式不正确,并且可以在传递给序列化程序之前进行组织,那么这些视图或函数应该负责使其格式正确。

case 2

让我们假设在LeadCreateSerializer中传递数据之前无法组织数据,那么我们需要在验证或获取lead_request期间获取相关值。因为这个serializer的责任是创建新实例并且为了验证字段所以我们假设在self.context中存在整个self.context.request

class LeadCreateSerializer(serializers.ModelSerializer):

    def generate_lead_request(self, data):
         # do your all possible validation and return 
         # in dict format

    def get_lead_request(self):
        request = self.context.request
        lead_request = self.generate_lead_request(request.data)
        return lead_request

    class Meta:
        model = Leads
        fields = ['campaign_id',
                  'lead_email',
                  'lead_request']
© www.soinside.com 2019 - 2024. All rights reserved.