gpt4 book ai didi

python - Django REST 框架 : return 404 (not 400) on POST if related field does not exist?

转载 作者:太空狗 更新时间:2023-10-30 00:36:01 26 4
gpt4 key购买 nike

我正在开发一个 REST API,它从一些无法 PATCH 或其他任何东西的真正脑残软件接收 POST 请求。 POST 用于更新数据库中已存在的模型对象。

具体来说,我正在为具有相关字段(SlugRelatedField,因为 POSTer 知道“名称”属性但不知道“pk”)的对象发布数据。但是,如果 POSTer 发送数据,其中“名称”在 SlugRelatedField 上不返回任何内容(例如,相关对象不存在),我需要返回 404。我已经通过调试器完成了这个,但 DRF 似乎使用了一些 Django 信号魔术来完成 DRF Does It™ 的方式,即返回 400 BAD REQUEST。我不知道如何修改它 - 当它是上述条件而不是真正的 400-worthy POST - 到 404。

顺便说一句,在我看来,pre_save() 在失败测试的执行过程中并未执行。

这是序列化程序:

class CharacterizationSerializer(serializers.ModelSerializer):
"""
Work-in-progress for django-rest-framework use. This handles (de)serialization
of data into a Characterization object and vice versa.

See: http://www.django-rest-framework.org/tutorial/1-serialization
"""
creator = serializers.Field(source='owner.user.username')
sample = serializers.SlugRelatedField(slug_field='name',
required=True,
many=False,
read_only=False)

class Meta:
model = Characterization
# leaving 'request' out because it's been decided to deprecate it. (...maybe?)
fields = ('sample', 'date', 'creator', 'comments', 'star_volume', 'solvent_volume',
'solution_center', 'solution_var', 'solution_minimum', 'solution_min_stddev',
'solution_test_len',)

这是 pre_save 未在给定测试中运行的 View (但在其他一些测试中运行):

class CharacterizationList(generics.ListCreateAPIView):
queryset = Characterization.objects.all()
serializer_class = CharacterizationSerializer
permission_classes = (AnonPostAllowed,) # @todo XXX hack for braindead POSTer

def pre_save(self, obj):
# user isn't sent as part of the serialized representation,
# but is instead a property of the incoming request.
if not self.request.user.is_authenticated():
obj.owner = get_dummy_proxyuser() # this is done for CharacterizationList so unauthed users can POST. @todo XXX hack
else:
obj.owner = ProxyUser.objects.get(pk=self.request.user.pk)

# here, we're fed a string sample name, but we need to look up
# the actual sample model.
# @TODO: Are we failing properly if it doesn't exist? Should
# throw 404, not 400 or 5xx.
# except, this code doesn't seem to be run directly when debugging.
# a 400 is thrown; DRF must be bombing out before pre_save?
obj.sample = Sample.objects.get(name=self.request.DATA['sample'])

为了更好的衡量,这是失败的测试:

def test_bad_post_single_missing_sample(self):
url = reverse(self._POST_ONE_VIEW_NAME)

my_sample_postdict = self.dummy_plqy_postdict.copy()
my_sample_postdict["sample"] = "I_DONT_EXIST_LUL"
response = self.rest_client.post(url, my_sample_postdict)
self.assertTrue(response.status_code == 404,
"Expected 404 status code, got %d (%s). Content: %s" % (response.status_code, response.reason_phrase, response.content))

如果我在 self.rest_client.post() 调用中放置一个断点,那时候响应中已经有一个 400。

最佳答案

您可以为此使用 Django 快捷方式,获取 obj.sample:

from django.shortcuts import get_object_or_404
obj.sample = get_object_or_404(Sample, name=self.request.DATA['sample'])

关于python - Django REST 框架 : return 404 (not 400) on POST if related field does not exist?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24420303/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com