1

I'm newbie with python and django and now I'm learning how to simplify code in writing the if ..else statements in one line.

But in this case I have a two querysets with a little change . I want to know if it is possible to simlify this code in one line

 if self.booked:
     x = qs.filter(content_id=content_id, object_id=model.id, action=10)
 else:
     x = qs.filter(content_id=content_id, object_id=model.id).exclude(action=10)
 return x
rahma
  • 33
  • 5
  • 4
    The entire point of "pythonic" code is that it is clear and readable. IMO there isn't a way to write this in one line that you can argue is clear and readable, so I would keep it as is. A tip is to try and keep each line of code within 80 characters wide. – steve Nov 14 '16 at 08:45

3 Answers3

0

This is possible, but makes the result hard to read:

return qs.filter(content_id=content_id, object_id=model.id, action=10) if self.booked else qs.filter(content_id=content_type_id, object_id=model.id).exclude(action=10)
Maurice
  • 11,482
  • 2
  • 25
  • 45
  • Thanks for your quick response. But the queryset is almost similar. there is only a small difference . is there a way to not duplicate the code ? – rahma Nov 14 '16 at 08:49
0

The if self.booked condition looks very important and it's in your good interest to make it stand out in your code.

But if you want to simplify, you could extract the common part of the query sets:

qs = qs.filter(object_id=model.id)
if self.booked:
    qs = qs.filter(content_id=content_id, action=10)
else:
    qs = qs.filter(content_id=content_type_id).exclude(action=10)
return qs
Kos
  • 70,399
  • 25
  • 169
  • 233
0

I would rephrase it so the common parts are outside of the if:

qs = qs.filter(content_id=content_id, object_id=model.id)
return qs.filter(action=10) if self.booked else qs.exclude(action=10)

Although it looks quite cryptic, especially because action 10 is hardcoded. You should define a constant with a clear name for it, at least.

Edit: wow, this is actually wrong, because in one side of the if you filter on content_id, and the other on content_type_id. Is that my bug or yours? At least it's proof that your code is hard to read...

RemcoGerlich
  • 30,470
  • 6
  • 61
  • 79
  • You can eliminate a bit more repetition with `return (qs.filter if self.booked else qs.exclude)(action=10)`. – TigerhawkT3 Nov 14 '16 at 09:11
  • @TigerhawkT3: well spotted, but would you write that in production code? – RemcoGerlich Nov 14 '16 at 09:15
  • @RemcoGerlich - Depends on my mood at the time. :) – TigerhawkT3 Nov 14 '16 at 09:17
  • if "it looks quite cryptic" it is not a good solution! Code should strive to be clear and easily understood by the next developer. – zaph Nov 14 '16 at 12:32
  • @zaph: I meant that it looks cryptic because it's not clear what action 10 is, or why only that action should be shown if self.booked and all the others otherwise; but I can't fix that. – RemcoGerlich Nov 14 '16 at 12:37