dee*_*ena 0 python django refactoring dry django-queryset
我写了一个查询具有已知查找类型的模型.表示输入类型传递的标志kwargs.下面kwarg将解释查找以及传递的kwargs.
db_hash=True)name=True)124,或134as id=True)例如,只是为了方法调用的名称,
self.check_all_routes("Sam", "452", name=True)
Run Code Online (Sandbox Code Playgroud)
我想重构下面的方法来减少它在违反DRY时产生的混乱.
def check_all_routes(self, driver, route, **kwargs):
_hash = kwargs.get('db_hash')
_name = kwargs.get('name')
_id = kwargs.get('id')
if _hash:
return self.model.objects.filter(
driver__db_hash=driver,
route__db_hash=route
).prefetch_related().select_related().values_list('route_number')
if _name:
return self.model.objects.filter(
driver__name=driver,
route__name=route
).prefetch_related().select_related().values_list('route_number')
if _id:
return self.model.objects.filter(
driver_id=driver,
route_id=route
).prefetch_related().select_related().values_list('route_number')
return self.model.objects.filter(
driver=driver,
route=route
).prefetch_related().select_related().values_list('route_number')
Run Code Online (Sandbox Code Playgroud)
可以做些什么来使它不违反DRY.
你可以这样做:
def check_all_routes(self, driver, route, **kwargs):
queries = {
"db_hash": ['driver__db_hash', 'route__db_hash'],
"name": ['driver__name', 'route__name'],
"id": ['driver_id', 'route_id'],
"default": ['driver', 'route']
}
arg = next((k for k, v in kwargs.items() if v), 'default')
params = queries[arg]
query = dict(zip(params, [driver, route]))
return self.model.objects.filter(**query).prefetch_related().select_related().values_list('route_number')
Run Code Online (Sandbox Code Playgroud)
这有点神奇,但最重要的部分是建立一个字典,然后filter使用**dict扩展语法传递给它.
(注意,我不确定你的查询是否正确;这些都检查路由和驱动程序是否匹配值,这似乎不一定是真的.)