我正在开发一个REST API,它接收来自一些真正的脑死亡软件的POST请求,这些软件无法修补或其他任何东西。文章将更新数据库中已经存在的模型对象。
具体来说,我发布的是具有相关字段(SlugRelatedField,海报知道“name”属性,但不知道“pk”)的对象的数据。但是,如果海报发送数据,而“name”在SlugRelatedField上不返回任何内容(例如,相关对象不存在),则需要返回404。我已经用一个调试器完成了这个过程,但是看起来DRF使用了一些Django信号魔法来完成它,就像DRF那样™,这将返回400个错误请求。我不知道如何修改这个-只有当它是上述条件,而不是一个真正的400有价值的职位-成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
不是在给定的测试中运行(而是在其他一些测试中运行):
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:
与其在API视图中使用
pre_save
为什么不重写post
:确保导入DRF的状态:
另外,请注意,除了捕获到的异常之外,您可能希望更加具体。如果没有匹配项,Django的
get
方法将返回DoesNotExist
;如果有多个对象匹配,则返回MultipleObjectsReturned
。The relevant documentation:相关问题 更多 >
编程相关推荐