How to get time slot in django for doctor appointment - django

I have two models Schedule and Appointment.
How can I get the duration of doctor in a different time slots for 15 minutes. I am getting blank in this
models.
class Schedule(models.Model):
doctor=models.ForeignKey(Doctor)
open=models.TimeField()
close=models.TimeField()
class Appointment(models.Model):
patient=models.ForeignKey(Patient)
doctor=models.ForeignKey(Doctor)
date=models.DateField()
time_slot=models.TimeField()

Based on the discussion we had in the comments, I will not provide you the exact code(as you have not done anything yet). But I will explain you different approaches(I can think right now) you can take.
Scheduler approach
First you can convert the timeslot into numbers, like 10:00 becomes 1, 10:15 becomes 1 and so on until the end time and every-time till the end of time(i.e 6pm in your case), store this as array in the timeslot field. Now every-time someone books a slot, just remove the number from the timeslot. Now if someone tires to book the same time slot you see that this number is not available and you don't let them book it or, every-time the page is reloaded you deactivate the slot for the user. The problem is that everyday you have to restore the array(timeslot) to blank before 10:00.(You might need a scheduler like django-beats).
More Generic way
Here what you do is in the table Appointment, make timeslot a number (it is just a number not array, but numbers follow the same pattern like above 10:00 becomes 1, 10:15 becomes 1 etc). Now everytime you load you page for the first time you query that give me all the appointments with this doctor for the day, initially it will be empty, hence you show all the available time slots. Once some user/patient books a timeslot you just need to create a entry in the Appointment with the patient, doctor, date, timeslot(you can hard code the appointment number on the frontend. like 10 bootstrap cards which show the 15 min timeslot and have different numbers, as you already know timeslot numbers i.e 10:00-> 1, you will receive the timeslot in backend and reserve the slot for the patient.) Now query all the time slots doctor have for the day and don't show the ones which are already booked(appointment table will tell you that).
These are two ways I can think right now, I will add more as I get to realise.
This should give you a direction for now at least.
Ask for details in comments, I will update the answer accordingly.

Here is the solution for that problem.
from django.db import models
class Appointment(models.Model):
"""Contains info about appointment"""
class Meta:
unique_together = ('doctor', 'date', 'timeslot')
TIMESLOT_LIST = (
(0, '09:00 – 09:30'),
(1, '10:00 – 10:30'),
(2, '11:00 – 11:30'),
(3, '12:00 – 12:30'),
(4, '13:00 – 13:30'),
(5, '14:00 – 14:30'),
(6, '15:00 – 15:30'),
(7, '16:00 – 16:30'),
(8, '17:00 – 17:30'),
)
doctor = models.ForeignKey('Doctor',on_delete = models.CASCADE)
date = models.DateField(help_text="YYYY-MM-DD")
timeslot = models.IntegerField(choices=TIMESLOT_LIST)
patient_name = models.CharField(max_length=60)
def __str__(self):
return '{} {} {}. Patient: {}'.format(self.date, self.time, self.doctor, self.patient_name)
#property
def time(self):
return self.TIMESLOT_LIST[self.timeslot][1]
class Doctor(models.Model):
"""Stores info about doctor"""
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
middle_name = models.CharField(max_length=20)
specialty = models.CharField(max_length=20)
def __str__(self):
return '{} {}'.format(self.specialty, self.short_name)
#property
def short_name(self):
return '{} {}.{}.'.format(self.last_name.title(), self.first_name[0].upper(), self.middle_name[0].upper())
To get the whole source code go to Click here!

Related

Date on which maximum number of tasks were completed in a single day django

I have 2 models like this. one user can have multiple tasks
class User(models.Model):
userCreated_at=models.DateTimeField(blank=True)
class Tasks(models.Model):
owner=models.ForeignKey(User , on_delete=models.CASCADE)
title = models.CharField(max_length=100,null=True,blank=True)
completion_date_time = models.DateTimeField(blank=True)
So I want to calculate .
Since time of account creation of user , on what date, maximum number of tasks were completed in a single day . Any help would be highly appericiated
Since you can only complete a task after the user is created, you should not worry about the "account creation date"
Instead, doing Tasks.objects.filter(owner=request.user) should give you a queryset containing all the tasks.
Finding the date when the most number of tasks were completed by a user will be hard using this data model, but maintaining a table with the same will be easy. Here's how you would do it:
class user_max_date(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE) #Need to import usermodel
date = models.DateTimeField(blank=True)
Now everytime a new task is completed, you have to check if the tasks completed today are more than the max tasks completed. In which case we will update this max_task_date
So here's how that would work:
today = date.today() #Will require datetime imports
tasksDoneToday = Tasks.objects.filter(owner=request.user).filter(completion_date_time__year=today.year,
completion_date_time__month=today.month,
completion_date_time__day=today.day)
max_date = request.user.user_max_date.date.date()
max_tasks_done = Tasks.objects.filter(owner=request.user).filter(completion_date_time__year=max_date.year,
completion_date_time__month=max_date.month,
completion_date_time__day=max_date.day)
if len(max_tasks_done) < len(tasks_done_today):
temp = request.user.user_max_date
temp.date = today
temp.save()
You will need to add this logic to your views.py in the view used to complete the tasks, or you can add a signal that executes this logic.

Django - substracting time

Welcome I have a problem. What field should be in model to substract times. I mean for example: 1st car made 500h 28 mins, 2nd car made 350h 15 min and i need a column substract where I'll have substraction from this two times. I made currently working model but only on integer field. When i tried time field and add something like 500:28 it gave me an error " incorrect time".
Current model:
class Aircraft (models.Model):
id = models.AutoField(primary_key=True)
registration = models.CharField(max_length=7)
#hours to maintenance
hours_to_maintenance = models.IntegerField(help_text = "test", null = True)
#current hours
ch = models.IntegerField(help_text = "test", null = True)
#rm = models.IntegerField(help_text = "test", null = True)
added_by = models.ForeignKey('auth.User', on_delete = models.CASCADE,)
def __str__(self):
return self.registration
Really thanks for help
Django has a field type designated for this type of data: DurationField. See the docs: Django DurationField
You’re definitely going to want to use a models.DateTimeField(...). This object is a python Date object. Here’s the documentation https://docs.python.org/2/library/datetime.html.
Make sure you click on the DateTime objects in the left nav panel
It’s really important you read the documentation because this will layout in more detail stack exchange can provide on this solution.
If you want to know how many minutes are between two DateTime values, you’ll have to calculate it using the min, hr, day etc attributes.

cross instance calculations in django queryset

Not sure that it's (a) doable and (b) if I formulate the task correctly. Perhaps the right way is refactoring the db design, but I would appreciate any opinion on that.
I have a model in django app, where I track the times a user enters and exits a certain page (via either form submission or just closing the broswer window). I do tracking using django channels, but it does not matter in this case.
The model looks like:
class TimeStamp(models.Model):
class Meta:
get_latest_by = 'enter_time'
page_name = models.CharField(max_length=1000)
participant = models.ForeignKey(to=Participant, related_name='timestamps')
timestamp = models.DateTimeField()
enter_exit_type = models.CharField(max_length=1000, choices=ENTEREXITTYPES,)
What I need to do is to calculate how much time a user spends on this page. So I need to loop through all records of Timestamp for the specific user, and calculate time difference between records of 'enter' and 'exit' types records.
So the db data may look like:
id timestamp enter_exit_type
1 20:12:12 enter
2 20:12:13 exit
3 20:18:12 enter
4 20:21:12 exit
5 20:41:12 enter
so what is the right way to produce a resulting queryset that look like:
id time_spent_sec
1 0:01
2 3:00
The last 'enter' record is ignored because there is no corresponding 'exit' record.
The record 1 in resulting queryset is difference between timestamps in ids 2 and 1. The record 2 in resulting queryset is difference between timestamps in ids 4 and 3.
I can just loop through the records, looking for the nearest 'exit' record and calculate it but I was thinking if there is a simpler solution?
It's possible:
1) Use the approach here to group by user if you want to get answer for all users in one query.
2) filter out the last unclosed entry with enter_exit_type == 'enter'.
3) .annotate(timestamp_with_sign=Case(When(enter_exit_type='exit', then=F('timestamp') * -1), default=F('timestamp'), )
4) Sum() by the timestamp_with_sign field.
I'm not sure, that F('timestamp') would work, you may need to search for the way to convert it to unix time.
This model structure may not be sufficient for your requirement. So I would suggest to change your model as,
class TimeStamp(models.Model):
class Meta:
get_latest_by = 'enter_time'
page_name = models.CharField(max_length=1000)
participant = models.ForeignKey(Musician, related_name='timestamps')
enter = models.DateTimeField()
exit = models.DateTimeField(null=True, blank=True)
Then you will get the data as,
from django.db.models import F, Sum, ExpressionWrapper, DurationField
TimeStamp.objects.values(
'participant').annotate(
sum_time_diff=Sum(
ExpressionWrapper(F('exit') - F('enter'), output_field=DurationField())
)
)
The response be like,
<QuerySet [{'participant': 1, 'sum_time_diff': datetime.timedelta(0, 7)}, {'participant': 2, 'sum_time_diff': datetime.timedelta(0, 2)}]>

how to implement a Model for these needs

say I have the following model:
Class Classroom(models.Model):
name = CharField(max_length=128)
Initially, I want this Classroom to be available to be occupied on every weekend of the year(both on Saturday and Sunday). A person, can then come and occupy/rent the classroom for a certain day. For example, Mr. Foo sees that it is available and wants to occupy it this Satuday, on 27th of September. What is a solution(or the best one) to implement this logic?
What is the approach? should I create another table and which? What type of fields should I add?
Thanks a lot!
Maybe something like this could work:
class Appointment(models.Model):
day = models.DateField()
available = models.BooleanField(default=True)
classroom = models.ManyToManyField(Classroom, related_name='appointments')
EDIT:
Availability should be rather placed in the middle table between Classroom and Appointment and the ManyToManyField should have through=tablename where tablename is the name of this table.
EDIT:
Actually I wanted to have a supper, but this question is now more important than my appetite :)
class Classroom(models.Model):
name = CharField(max_length=128)
class WeekendDay(models.MOdel): # this was before Appointment
day = models.DateField()
classroom = models.ManyToManyField(Classroom, through="Appointment")
class Appointment(models.Model)
available = models.BooleanField(default=True)
weekend_day = models.ForeignKey(WeekendDay, related_name='appointments_per_day')
classroom = models.ForeignKey(Classroom, related_name='appointments_per_classroom')
I think something like this should work, if you have many classrooms, which are available on many days. Through the field available you can see or set the availability. If a classroom is booked let's say on next Saturday, then its value should be set to False. This should be the basic skeleton, you can extend the models according to your needs.

Django: Distinct on forgin key relationship

I'm working on a Ticket/Issue-tracker in django where I need to log the status of each ticket. This is a simplification of my models.
class Ticket(models.Model):
assigned_to = ForeignKey(User)
comment = models.TextField(_('comment'), blank=True)
created = models.DateTimeField(_("created at"), auto_now_add=True)
class TicketStatus(models.Model):
STATUS_CHOICES = (
(10, _('Open'),),
(20, _('Other'),),
(30, _('Closed'),),
)
ticket = models.ForeignKey(Ticket, verbose_name=_('ticket'))
user = models.ForeignKey(User, verbose_name=_('user'))
status = models.IntegerField(_('status'), choices=STATUS_CHOICES)
date = models.DateTimeField(_("created at"), auto_now_add=True)
Now, getting the status of a ticket is easy sorting by date and retrieving the first column like this.
ticket = Ticket.objects.get(pk=1)
ticket.ticketstatus_set.order_by('-date')[0].get_status_display()
But then I also want to be able to filter on status in the Admin, and those have to get the status trough a Ticket-queryset, which makes it suddenly more complex. How would I get a queryset with all Tickets with a certain status?
I guess you are trying to avoid a cycle (asking for each ticket status) to filter manually the queryset. As far as I know you cannot avoid that cycle. Here are ideas:
# select_related avoids a lot of hits in the database when enter the cycle
t_status = TicketStatus.objects.select_related('Ticket').filter(status = ID_STATUS)
# this is an array with the result
ticket_array = [ts.ticket for ts in tickets_status]
Or, since you mention you were looking for a QuerySet, this might be what you are looking for
# select_related avoids a lot of hits in the database when enter the cycle
t_status = TicketStatus.objects.select_related('Ticket').filter(status = ID_STATUS)
# this is a QuerySet with the result
tickets = Tickets.objects.filter(pk__in = [ts.ticket.pk for ts in t_status])
However, the problem might be in the way you are modeling the data. What you called TickedStatus is more like TicketStatusLog because you want to keep track of the user and date who change the status.
Therefore, the reasonable approach is to add a field 'current_status' to the Ticket model that is updated each time a new TicketStatus is created. In this way (1) you don't have to order a table each time you ask for a ticket and (2) you would simply do something like Ticket.objects.filter(current_status = ID_STATUS) for what I think you are asking.