我在我的类方法中需要一些OR过滤,但我觉得这段代码非常糟糕。这应该是怎么回事?或者我可以设计得更好一点吗?
class FooBar:
@classmethod
def get_current_objects(cls, role='passenger',
add_params=None, offset=0, limit=10):
"""
The logic behind this is to return cls.objects with filters
defined in params var, but I stumbled accross
the need to use OR in the query, whilst keeping some `add_params`
in `params` var.
"""
params = {}
# ... here are some 'params', lots of code I need to keep, skipped ...
if add_params:
# this piece below feels awkward
for k, v in add_params.copy().iteritems():
if (v == True) and (role == 'passenger'):
add_args.append(Q(**{k: True}) | Q(**{k: False}))
del add_params[k]
elif (v == False) and (role == 'driver'):
add_args.append(Q(**{k: True}) | Q(**{k: False}))
del add_params[k]
elif (type(v) == str) and (role == 'passenger'):
add_args.append(Q(**{k: v}) | Q(**{k: u''}))
del add_params[k]
elif (type(v) == str) and (role == 'driver'):
add_args.append(Q(**{k: v}) | Q(**{k: u''}))
del add_params[k]
params.update(add_params)
# -----------------------------
return cls.objects.filter(*add_args, **params)[offset:offset + limit]
在这种情况下我怎么不重复自己?
答案 0 :(得分:1)
我不完全确定语法,但这就是我写它的方式。
if add_params:
# this piece below feels awkward
for k, v in add_params.copy().iteritems():
if ((v == true) and (role == 'passenger')) # edited the true/false in
or ((v == false) and (role == 'driver')):
add_args.append(Q(**{k: True}) | Q(**{k: False}))
del add_params[k]
elif (type(v) == str) # (x or y) and (x or z) -> x and (y or z)
and ((role == 'passenger') or (role == 'driver')):
add_args.append(Q(**{k: v}) | Q(**{k: u''}))
del add_params[k]
params.update(add_params)
# -----------------------------
return cls.objects.filter(*add_args, **params)[offset:offset + limit]