django - 保持 Django 视图干净的上下文管理器?
问题描述
我已经问过类似的问题,但这太宽泛了,不是 Django 特有的。使用上下文管理器保持 Django 视图清洁以使代码干燥是一种好习惯吗?这是代码示例(有点伪代码):
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)
有了这个重构代码看起来就简单多了,但是如果我可以用这种方式使用上下文管理器,我找不到信息,但这不是禁止的风格吗?
解决方案
我不明白为什么要为此目的使用上下文管理器-在这里使用它们不会获得任何好处。只需调用
validate_data(a, b):
result = some_complicated_logic_another(a, b)
validate_data
应该足够了,必要时依靠引发错误。
但是既然你提到了,你正在使用 Django rest 框架,对我来说这似乎对序列化器和使用它们的验证系统很有用。当然,假设您get_data_from_somewhere1
使用request
数据作为输入(至少部分)。要调用序列化程序验证,您可以调用is_valid
,例如
serializer = MySerializer(data=request.data, context=...)
serializer.is_valid(raise_exception=True)
然后在序列化程序的validate
函数中,使用所需的状态代码引发适当的异常,例如ValidationError('my error msg')
(from rest_framework.exceptions
)。
或者您可以简单地从您的函数中提升ValidationError
(或扩展它以覆盖其默认值status_code
,如果需要) 。validate_data()
推荐阅读
- android-studio - adb.exe 已停止使用 Android Studio 4.3.1 和 Android 9.+
- javascript - 在 POST 方法中通过 ajax call() 将参数传递给 api
- ios - 在 SwiftUI 的自定义视图中访问图像的修饰符
- c++ - 使用 Qt 应用程序在 iOS 上以后台模式获取 GPS 数据
- fortran - fortran 中的数据语句
- matlab - 如何使用符号工具箱将用户创建的函数从 GUI 转换为接受参数的 matlab 函数
- laravel - Laravel:发送电子邮件:错误(加载cafile流失败)
- javascript - TypeScript:类型 A 的索引键和类型 B 的保留键
- javascript - 使用 Javascript 从任何网站表单存储输入数据并将其发送到 webhook
- java - 为什么异步任务中的 ExecutorCompletionService 中的 take().get() 需要花费大量时间才能从其第一个完成的线程中获取结果?