我已经问过类似的问题,但这太广泛了,而不是特定于Django的。用上下文管理器保持Django视图干净以使代码DRY是一种好习惯吗?这是代码示例(有点伪代码):
class DjangoViewset():
@action(method=['GET'])
def custom_action1(request):
a = get_data_from_somewhere1()
b = get_data_from_somewhere2()
if a<b:
raise 400
if a==1:
raise 404
if a==2:
raise 403
result = some_complicated_logic(a, b)
return Response(result)
@action(method=['GET'])
def custom_action2(request):
a = get_data_from_somewhere1()
b = get_data_from_somewhere2()
if a<b:
raise 400
if a==1:
raise 404
if a==2:
raise 403
result = some_complicated_logic_another(a, b)
return Response(result)
我可以使用类似的东西重构它吗,或者使用上下文管理器这很不好?
@contextmanager
def validate_data(a, b):
if a<b:
raise 400
if a==1:
raise 404
if a==2:
raise 403
yield
class DjangoViewset():
@action(method=['GET'])
def custom_action1(request):
a = get_data_from_somewhere1()
b = get_data_from_somewhere2()
with validate_data(a, b):
result = some_complicated_logic(a, b)
return Response(result)
@action(method=['GET'])
def custom_action2(request):
a = get_data_from_somewhere1()
b = get_data_from_somewhere2()
with validate_data(a, b):
result = some_complicated_logic_another(a, b)
return Response(result)
有了这个重构代码,看起来要简单得多,但是如果我能以这种方式使用上下文管理器,我找不到信息,但这不是禁止的样式吗?
答案 0 :(得分:2)
我不明白为什么要为此使用上下文管理器-您在这里使用它们不会获得任何好处。只需致电
validate_data(a, b):
result = some_complicated_logic_another(a, b)
足够了,必要时依靠validate_data
引发错误。
但是,正如您提到的那样,您正在使用Django rest框架,对我来说,这对Serializers并使用其验证系统似乎是一个很好的用法。当然,假设您的get_data_from_somewhere1
使用request
数据作为输入(至少部分)。
要调用序列化程序验证,您可以调用is_valid
,例如
serializer = MySerializer(data=request.data, context=...)
serializer.is_valid(raise_exception=True)
然后在序列化程序的validate
函数中,使用所需的状态代码(例如, ValidationError('my error msg')
(来自rest_framework.exceptions
)。
或者您可以从ValidationError
函数中提高status_code
(或扩展它以覆盖其默认validate_data()
)。
答案 1 :(得分:0)
在我看来,这是对上下文管理器的不当使用,因为它没有提供任何真实的上下文。通常,上下文管理器会提供一些上下文,例如数据库连接或文件句柄,这需要在进入和退出上下文(例如打开和关闭数据库连接)时完成工作。
为什么不只是将验证逻辑放在常规函数中?
def validate_data(a, b):
if a<b:
raise 400
if a==1:
raise 404
if a==2:
raise 403
然后做
validate_data(a, b):
result = some_complicated_logic(a, b)
在您看来,您知道执行逻辑时已验证数据。