REST Django - 无法从我的验证器中找到请求的上下文
请温柔一点。我是 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为您不需要担心检查请求是否是
validate_media()
方法内的 POST。通常验证仅在 POST、PATCH 和 PUT 请求期间发生。最重要的是,仅当您在序列化器上调用is_valid()
时才会进行验证,通常是在视图中显式调用,就像在post()
函数中所做的那样。只要您从未从post()
以外的任何地方调用is_valid()
,您就知道这是一个 POST。由于您不支持patch()
或put()
在您看来,那么这应该不是问题。您必须在创建序列化器时显式传递上下文才能使其存在。这里没有魔法。正如您在 源代码 当您不传入时,
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 callis_valid()
on the serializer, often explicitly in a view, as you do in yourpost()
function. As long as you never callis_valid()
from anywhere other thanpost()
, you know that it is a POST. Since you don't supportpatch()
orput()
in your view, then this shouldn't be a problem.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:
Even better, just pass in the method:
You can make the
context
dictionary whatever you want.