【问题标题】:How to add extra key in created object in Django Rest Framework?如何在 Django Rest Framework 中创建的对象中添加额外的键?
【发布时间】:2022-02-12 15:02:07
【问题描述】:

我是 Django 新手

目前我正在尝试在序列化程序中返回的 json 上添加一个简单的额外键。这是我的序列化程序的 create() 覆盖:

    def create(self, validated_data):
        available_dates = validated_data.pop("available_dates")

        # Default expiry time is 3 days
        expiry = datetime.datetime.now() + datetime.timedelta(days=3)
        event = Events.objects.create(**validated_data, expiry=expiry)
        for selectedTime in available_dates:
            AvailableDates.objects.create(
                event=event,
                **selectedTime,
            )

        signer = Signer()
        signedObject = signer.sign_object(
            {"expiry": expiry.isoformat(), "id": event.id}
        )

        return {**event, "signed_url": signedObject}

如你所见,我不想只返回事件,但我想添加一个签名的 url。

这给了我一个错误: 'Events' object is not a mapping

那么我该如何添加额外的密钥呢?我在 create 函数中返回什么?我可以在 DRF 中创建 Response() 作为 create 函数的返回吗?

【问题讨论】:

  • create 用于在数据库中创建一个新的模型对象。你宁愿覆盖to_representation?!
  • 对.. 但是如果我只想在创建后返回 url 怎么办?我应该定制哪个部分?
  • 这是什么意思?!
  • 我的意思是我只想添加 signed_url 键作为我的 post 端点的返回(创建新行时)。 @deceze。希望有意义

标签: python django django-rest-framework


【解决方案1】:

序列化器的.create() 方法需要返回创建的实例。创建成功后,在访问serializer.data时作为序列化程序的实例(就像它在retrieve api中的使用方式一样)


至于添加signed_url,您可以将其添加到序列化程序的字段中,例如:

class EventSerializer(ModelSerializer):
   # other fields ...
   signed_url = SerializerMethodField()

   class Meta:
       model = Event
       fields = [
           # other fields ...
           "signed_url",
       ]

   def create(self, validated_data):
        available_dates = validated_data.pop("available_dates")

        # Default expiry time is 3 days
        expiry = datetime.datetime.now() + datetime.timedelta(days=3)
        event = Events.objects.create(**validated_data, expiry=expiry)
        for selectedTime in available_dates:
            AvailableDates.objects.create(
                event=event,
                **selectedTime,
            )

        signer = Signer()
        signedObject = signer.sign_object(
            {"expiry": expiry.isoformat(), "id": event.id}
        )
        event.signedObject = signedObject

        return event
    def get_signed_url(self,obj):
         if not hasattr(obj, "signedObject"):
             return None
         # you can add other code here if you need to do something else with signedObject
         return obj.signedObject

还有其他方法可以做到这一点。但是上面的可能会根据提供的代码来做。

【讨论】:

  • 感谢您的回答,我终于选择了to_representation,但是您的也可以。因此我会接受它作为其他人看到的答案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-16
  • 1970-01-01
  • 1970-01-01
  • 2018-12-05
  • 2015-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多