Reputation: 91
i have 4 variables here that needs to check whether its true or false. together will all the combinations.. 4 true, 3 true 1 false, 2 true 2 false, 1 true 3 false and all false.. in total this will make like 10++ condition (a bit lazy to count).
if game and owner and platform and is_new and for_sale:
game_copy = GameCopy.objects.all()
elif game:
game_copy = GameCopy.objects.filter(game=game)
elif platform:
game_copy = GameCopy.objects.filter(platform=platform)
elif owner:
game_copy = GameCopy.objects.filter(user=owner)
elif is_new:
game_copy = GameCopy.objects.filter(is_new=is_new)
elif for_sale:
game_copy = GameCopy.objects.filter(for_sale=for_sale)
else:
game_copy = GameCopy.objects.all()
return game_copy
im looking for a leaner approach for this condition.. hopefully ended with something with 5 to 10 lines
Upvotes: 1
Views: 753
Reputation: 25489
You could add everything that's truthy to a dictionary and then pass those to the function by unpacking keyword arguments.
args = { "game": game, "owner": owner, "platform": platform, "is_new": is_new, "for_sale": for_sale }
# check if all args are truthy
all_args = all(v for v in args.values())
# filter out only the truthy args
filtered_args = {k: v for k, v in args.items() if v}
if all_args or not filtered_args:
# if all_args is true or filtered_args is empty
game_copy = GameCopy.objects.all()
else:
# Unpack filtered_args into filter()
game_copy = GameCopy.objects.filter(**filtered_args)
Upvotes: 5
Reputation: 2423
You could change your variable to a set of flags (bits set in a unique integer)
GAME = 1 << 0 # 1
OWNER = 1 << 1 # 2
PLATFORM = 1 << 2 # 4
IS_NEW = 1 << 3 # 8
FOR_SALE = 1 << 4 # 16
# for instance flags = GAME
# or flags = OWNER | IS_NEW
# ensures that there is only one flag set and pass it to you filter
if (flags & (flags-1) == 0) and flags != 0:
game_copy = GameCopy.objects.filter(flags)
# Otherwise
else: game_copy = GameCopy.objects.all()
return game_copy
Upvotes: 1