Basically, I am listing family but list "Spouse" relationship at the top.
Say I have data structure like this:
class Family:
def __init__(self, type, name):
self.type = type
self.name = name
def __repr__(self):
return repr((self.type, self.name))
fam = [
Family("child", "Joi"),
Family("child", "Leona"),
Family("parent", "Toshiko"),
Family("spouse", "Coy"),
Family("parent", "Akira"),
]
In SQL statement (PostgreSQL) I can express like this.
SELECT * FROM family WHERE ...... ORDER BY CASE WHEN type='Spouse' THEN 'aaa' else type END
Easy enough.
Now I wasn't sure how to do this in Django.
With raw sql or extras filter code becomes pgSQL specific solution so I wanted to avoid if possible.
So I decided to go with pure python function "sorted" since set of data I will be dealing with is small (just family members... so usually like 4 or 5 and at most... 10?)
Here is how I was able to accomplish.
>>> print(fam)
[('child', 'Joi'), ('child', 'Leona'), ('parent', 'Toshiko'), ('spouse', 'Coy'), ('parent', 'Akira')]
>>> family = sorted(fam, key=lambda x: ("aaa" if x.type == "spouse" else x.type))
>>> print(family)
[('spouse', 'Coy'), ('child', 'Joi'), ('child', 'Leona'), ('parent', 'Akira'), ('parent', 'Toshiko')]
I don't probably need to explain what lambda or sorted with key param is as documentation and thousands of other posts are doing great job but I wanted to post this because I could not find example that shows this level of "key" for sorted function.
"key" will be return ('aaa') for Spouse and (<type>) for other relationship.
for x in family:
key=lambda x: ("aaa" if x.type == "spouse" else x.type)
print("%(name)s has type of %(type)s" % {"name": x.name, "type":key(x)})
>>> Coy has type of aaa
>>> Joi has type of child
>>> Leona has type of child
>>> Akira has type of parent
>>> Toshiko has type of parent
Ah-ha!
If you want to further specify sort order, you can add sort by name followed by type like this too.
family = sorted(fam, key=lambda x: ("aaa" if x.type == "spouse" else x.type, x.name))
Hope this magic became clear to you as well.
No comments:
Post a Comment