Best way to save availability of user over days of week in python/django
I want to store users preferences for day(s) of week he might be available. e.g. A user can be available on saturday, sunday but not on other days. Currently I am using array of 7 checkboxes(values=1,2,...7) so that user can select individual days of his availability.
Now the first question is how can i store this in database. I am thinking of using a string(length=7) and storing preferences like 1100010 where 1 will signify available and 0 not available. Is it good practice?
Second question, how开发者_运维问答 can I convert POST data (["1","2","7"]) into string (1100010)
1st - good solution, I'm doing mine similarly. 2nd - you should think of assigning each day power of 2, that way it'll be easy to convert those numbers to binary using bin() and easy to compare you'll just do &.
>>> mon, tue, wed, thu, fri, sat, sun = (pow(2, i) for i in range(7))
>>> bin(mon)
'0b1'
>>> bin(sun)
'0b1000000'
# create range:
>>> x = mon | wed | fri
>>> bin(x)
'0b10101'
# check if day is in range:
>>> x & mon
1
>>> x & tue
0
The problem with bin is that you must add 0's to the beginning to get 7 char long string, but you could also write your own version like this:
bin = lambda n:"".join([str((n >> y) & 1) for y in range(7-1, -1, -1)])
I found this implementation of a BitField by David Cramer, which should do what you want. Looks very nice.
It's kinda tricky, but given that weekdays are not going to change, your further code could be clearer if you add the column with each day's name into your availability table with 0 or 1 indicating availability. This may seem a bit redundant, but will be easier to code and maintain in the future.
Second question, how can I convert POST data (["1","2","7"]) into string (1100010)
week=['0']*7
for day in ["1","2","7"]:
week[int(day) - 1]='1'
week=''.join(week)
Another option would be to just store it as comma separated integers. Django has a builtin field for that: http://docs.djangoproject.com/en/1.2/ref/models/fields/#commaseparatedintegerfield
One other option is the more-or-less obvious one: define a table of the days of the week, and have a ManyToManyField
map one to the other. The admin would just work, you can do searches based on dates, and it works on SQLite unlike some of the functions in django-bitfield. Searches can be fast, since they're within the database and you don't have to use SQL's LIKE
(which ignores indexes if there are wildcards at the start of the string, which would be the case for CommaSeparatedIntegerField
or a seven-character string).
Sure, it takes more storage, but how many users do you have, anyway? Millions?
P.S. if you have an ordering field in your weekday table, you can also make the database sort by day of week for you with something like queryset.order_by('available__order')
.
I'd go for separate boolean columns.
It'll be a lot easier for you to then query, say, for users that are available on mondays; or to count the number of users that available through every weekday, or whatever.
精彩评论