Best way to keep user accessible for several days of the week in python / django

I want to keep user preferences for the day (s) of the week that it may be available. for example, the User may be available on Saturday, Sunday, but not on other days. I am currently using an array of 7 flags (values ​​= 1,2, ... 7) so that the user can select individual days of availability.

Now the first question: how can I store this in a database. I am thinking about using a string (length = 7) and preserving preferences like 1100010, where 1 means it is available and 0 is not available. Is this a good practice?

The second question is, how can I convert the POST data (["1", "2", "7"]) to a string (1100010)

+4
source share
6 answers

This is quite complicated, but given that weekdays do not change, your further code may be clearer if you add a column every day in your availability table with 0 or 1 indicating availability. This may seem a bit redundant, but it will be easier to code and maintain in the future.

The second question is, how can I convert the POST data (["1", "2", "7"]) to a string (1100010)

week=['0']*7 for day in ["1","2","7"]: week[int(day) - 1]='1' week=''.join(week) 
+1
source

I found this DavidFramer BitField implementation that should do what you want. It looks very good.

+2
source

1st is a good solution, I do the same too. 2nd - you should consider assigning each power of day 2, so it’s easy to convert these numbers to binary using bin () and it's easy to compare, you 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 have to add 0 to the beginning to get a long string of length 7 char but you can also write your own version as follows:

 bin = lambda n:"".join([str((n >> y) & 1) for y in range(7-1, -1, -1)]) 
+2
source

Another option is to simply save it as integers, separated by commas. Django has a built-in field for this: http://docs.djangoproject.com/en/1.2/ref/models/fields/#commaseparatedintegerfield

+1
source

Another option is more or less obvious: define a table of days of the week and map ManyToManyField one another. The admin just works, you can search by dates, and it works on SQLite, unlike some functions in django-bitfield. Searches can be fast since they are in the database and you do not need to use SQL LIKE (which ignores indexes if there are wildcards at the beginning of the line, which will be the case for CommaSeparatedIntegerField or a seven-character string).

Of course, more memory is required, but how many users do you have, anyway? Millions?

PS if you have an ordered field in your day of the week table, you can also sort the database by day of the week for you with something like queryset.order_by('available__order') .

+1
source

I would choose individual boolean columns .

It will be much easier for you to request, say, users who are available on Monday; or count the number of users that are available every day of the week or something else.

0
source

Source: https://habr.com/ru/post/1341992/


All Articles