REST Django - 无法从我的验证器中找到请求的上下文

发布于 2025-01-12 03:02:26 字数 2913 浏览 3 评论 0原文

请温柔一点。我是 Django 新手,我发现抽象程度简直令人难以承受。

我的最终目标是修改进入模型的图像文件。该部分可能相关,也可能不相关,但我在这篇文章中得到了帮助,它建议我应该在验证器内进行更改: REST Django - 如何在将序列化文件放入模型之前对其进行修改

无论如何,目前我只是想获取请求的上下文,这样我就可以确保只有当请求是 邮政。然而,在我的验证器中, self.context 只是一个空字典。根据我在那里发现的内容, self.context['request'] 应该有一个值。 这是我所拥有的:

带有验证器方法的序列化器:

class MediaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Media
        fields = '__all__'

    def validate_media(self, data):
        print(self.context)
        #todo: why is self.context empty?
        #if self.context['request'].method == 'POST':
        #    print('do a thing here')
        return data

    def to_representation(self, instance):
        data = super(MediaSerializer, self).to_representation(instance)
        return data

视图以及 post 方法

class MediaView(APIView):
    queryset = Media.objects.all()
    parser_classes = (MultiPartParser, FormParser)
    permission_classes = [permissions.IsAuthenticated, ]
    serializer_class = MediaSerializer

    def post(self, request, *args, **kwargs):

        user = self.request.user
        print(user.username)

        request.data.update({"username": user.username})

        media_serializer = MediaSerializer(data=request.data)
        # media_serializer.update('username', user.username)
        if media_serializer .is_valid():
            media_serializer.save()
            return Response(media_serializer.data, status=status.HTTP_201_CREATED)
        else:
            print('error', media_serializer.errors)
            return Response(media_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

模型:

class Media(models.Model):
    objects = None
    username = models.ForeignKey(User, to_field='username',
                                 related_name="Upload_username",
                                 on_delete=models.DO_NOTHING)
    date = models.DateTimeField(auto_now_add=True)
    #temp_media = models.FileField(upload_to='upload_temp', null=True)
    media = models.FileField(upload_to='albumMedia', null=True)
    #todo: potentially this will go to a temp folder, optimize will be called and then permananent home will be used -jjb
    #MEDIA_ROOT path must be /src/upload
    file_type = models.CharField(max_length=12)
    MEDIA_TYPES = (
        ('I', "Image"),
        ('V', "Video")
    )
    media_type = models.CharField(max_length=1, choices=MEDIA_TYPES, default='I')

    ACCESSIBILITY = (
        ('P', "Public"),
        ('T', "Tribe"),
        ('F', "Flagged")
    )

    user_access = models.CharField(max_length=1, choices=ACCESSIBILITY, default='P')

所以我只是想弄清楚如何解决这个上下文问题。另外,如果有任何其他关于如何到达我要去的地方的提示,我将不胜感激。

PS我是新来的。如果我以不适合堆栈溢出的方式写这个问题,请友善,我会纠正它。谢谢。

Please be gentle. I'm a Django newb and I find the level of abstraction just plain overwhelming.

My ultimate goal is to modify an image file on its way into the model. That part may or may not be relevant, but assistance came my way in this post which advised me that I should be making changes inside a validator:
REST Django - How to Modify a Serialized File Before it is Put Into Model

Anyway, at the moment I am simply trying to get the context of the request so I can be sure to do the things to the thing only when the request is a POST. However, inside my validator, the self.context is just an empty dictionary. Based on what I have found out there, there should be a value for self.context['request'].
Here is what I have:

Serializer with validator method:

class MediaSerializer(serializers.ModelSerializer):
    class Meta:
        model = Media
        fields = '__all__'

    def validate_media(self, data):
        print(self.context)
        #todo: why is self.context empty?
        #if self.context['request'].method == 'POST':
        #    print('do a thing here')
        return data

    def to_representation(self, instance):
        data = super(MediaSerializer, self).to_representation(instance)
        return data

The view along with the post method

class MediaView(APIView):
    queryset = Media.objects.all()
    parser_classes = (MultiPartParser, FormParser)
    permission_classes = [permissions.IsAuthenticated, ]
    serializer_class = MediaSerializer

    def post(self, request, *args, **kwargs):

        user = self.request.user
        print(user.username)

        request.data.update({"username": user.username})

        media_serializer = MediaSerializer(data=request.data)
        # media_serializer.update('username', user.username)
        if media_serializer .is_valid():
            media_serializer.save()
            return Response(media_serializer.data, status=status.HTTP_201_CREATED)
        else:
            print('error', media_serializer.errors)
            return Response(media_serializer.errors, status=status.HTTP_400_BAD_REQUEST)

The Model:

class Media(models.Model):
    objects = None
    username = models.ForeignKey(User, to_field='username',
                                 related_name="Upload_username",
                                 on_delete=models.DO_NOTHING)
    date = models.DateTimeField(auto_now_add=True)
    #temp_media = models.FileField(upload_to='upload_temp', null=True)
    media = models.FileField(upload_to='albumMedia', null=True)
    #todo: potentially this will go to a temp folder, optimize will be called and then permananent home will be used -jjb
    #MEDIA_ROOT path must be /src/upload
    file_type = models.CharField(max_length=12)
    MEDIA_TYPES = (
        ('I', "Image"),
        ('V', "Video")
    )
    media_type = models.CharField(max_length=1, choices=MEDIA_TYPES, default='I')

    ACCESSIBILITY = (
        ('P', "Public"),
        ('T', "Tribe"),
        ('F', "Flagged")
    )

    user_access = models.CharField(max_length=1, choices=ACCESSIBILITY, default='P')

So I'm just trying to figure out how to fix this context problem. Plus if there are any other tips on how to get where I'm going, I'd be most appreciative.

PS I'm pretty new here. If I wrote this question in a way that is inappropriate for stack overflow, please be kind, and I will correct it. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

可爱暴击 2025-01-19 03:02:26

我认为您不需要担心检查请求是否是 validate_media() 方法内的 POST。通常验证仅在 POST、PATCH 和 PUT 请求期间发生。最重要的是,仅当您在序列化器上调用 is_valid() 时才会进行验证,通常是在视图中显式调用,就像在 post() 函数中所做的那样。只要您从未从 post() 以外的任何地方调用 is_valid(),您就知道这是一个 POST。由于您不支持 patch()put() 在您看来,那么这应该不是问题。

在我的验证器中,self.context 只是一个空字典

您必须在创建序列化器时显式传递上下文才能使其存在。这里没有魔法。正如您在 源代码 当您不传入时,context 默认为 {}

要传入上下文,您可以这样做:

        context = {'request': request}
        media_serializer = MediaSerializer(data=request.data, context=context)

更好的是,只需传入方法即可:

        context = {'method': request.method}
        media_serializer = MediaSerializer(data=request.data, context=context)

您能使 context 字典成为您想要的任何内容。

I don't think you need to worry about checking if the request is a POST inside the validate_media() method. Generally validation only occurs during POST, PATCH, and PUT requests. On top of that, validation only occurs when you call is_valid() on the serializer, often explicitly in a view, as you do in your post() function. As long as you never call is_valid() from anywhere other than post(), you know that it is a POST. Since you don't support patch() or put() in your view, then this shouldn't be a problem.

inside my validator, the self.context is just an empty dictionary

You must explicitly pass in context when creating a serializer for it to exist. There is no magic here. As you can see in the source code context defaults to {} when you don't pass it in.

To pass in context, you can do this:

        context = {'request': request}
        media_serializer = MediaSerializer(data=request.data, context=context)

Even better, just pass in the method:

        context = {'method': request.method}
        media_serializer = MediaSerializer(data=request.data, context=context)

You can make the context dictionary whatever you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文