将参数传递给 Django REST 框架序列化程序以与模型一起使用

Tin*_*tin 1 django django-serializer django-rest-framework

我有一个Object带有state日期时间参数的方法的类dt。如何将日期时间参数从 URL 传递到Object.state()

该模型:

class Object(models.Model):
    def state(self, dt=datetime.datetime.now()) -> dict:
        ...stuff...
        return {'dt': dt, 'other_stuff': stuff}
Run Code Online (Sandbox Code Playgroud)

风景:

class ObjectDetail(generics.RetrieveAPIView):
    queryset = models.Object.objects.all()
    serializer_class = serializers.ObjectSerializer

    def get_serializer_context(self):
        return {'dt': self.request.query_params.get('dt', datetime.datetime.now())}

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

和序列化器类:

class ObjectSerializer(serializers.HyperlinkedModelSerializer):
    state = StateSerializer(read_only=True, context={'dt': self.context['dt']})

    class Meta:
        model = models.Object
        fields = ('state')

class StateSerializer(serializers.Serializer):
    dt = serializers.DateTimeField()
    ... other stuff...
Run Code Online (Sandbox Code Playgroud)

如您所见,我试图在视图中较早设置上下文dt的行state = StateSerializer(read_only=True, context={'dt': dt})中作为额外上下文传递。这里的问题是无法通过as未定义访问何时ObjectSerializer初始化。dtself.context['dt']self

Tin*_*tin 5

解决办法是先做state一个serializers.SerializerMethodField(),然后再定义一个get_state方法。新的ObjectSeializer看起来像这样:

class ObjectSerializer(serializers.HyperlinkedModelSerializer):
    state = serializers.SerializerMethodField()

    class Meta:
        model = models.Object
        fields = ('state')

    def get_state(self, obj):
        state = obj.state(self.context['dt'])
        state_serializer = StateSerializer(state)
        return state_serializer.data
Run Code Online (Sandbox Code Playgroud)