passing the dates between two dates back into the formatday method - python

I'm learning Python and Django and am building a job management app, I have the following, which is all working ok, and displays the jobs on a HTML calendar. It displays the start and end dates okay, however if the job is more than two days there is a gap in the calendar as there is no date related to the job to show.
I can get the dates in between by doing the following;
start = job.start_time
end = job.end_time
between = end - start
for i in range(between.days + 1):
datesbetween = [start + timedelta(days=i)]
Below is my views.py file:
class AdminCalendarView(LoginRequiredMixin,PermissionRequiredMixin, ListView):
model = Job
template_name = 'jobs/admin_diary.html'
permission_required = 'jobs.add_job', 'raise_exception=True'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# use today's date for the calendar
d = get_date(self.request.GET.get('month', None))
# Instantiate our calendar class with today's year and date
cal = AdminCalendar(d.year, d.month)
jobs = Job.objects.filter(start_time__year=d.year, start_time__month=d.month)
# Call the formatmonth method, which returns our calendar as a table
html_cal = cal.formatmonth(jobs, withyear=True)
context['calendar'] = mark_safe(html_cal)
context['prev_month'] = prev_month(d)
context['next_month'] = next_month(d)
return context
The utils.py file:
from datetime import datetime, timedelta, date
from calendar import HTMLCalendar
from .models import Job
from django.db.models import Q
class AdminCalendar(HTMLCalendar):
def __init__(self, year=None, month=None):
self.year = year
self.month = month
super(AdminCalendar, self).__init__()
# formats a day as a td
# filter jobs by day
def formatday(self, day, jobs):
jobs_per_day = jobs.filter(Q(start_time__day=day) | Q(end_time__day=day))
d = ''
for job in jobs_per_day:
d += f"<a href='/job/{job.id}'> <li class='job-diary'> {job.client} Job: {job.id}</li> </a>"
if day != 0:
return f"<td><span class='date'>{day}</span><ul> {d} </ul></td>"
return '<td></td>'
# formats a week as a tr
def formatweek(self, theweek, jobs):
week = ''
i = [a_tuple[0] for a_tuple in theweek]
for d in i:
week += self.formatday(d, jobs)
return f'<tr> {week} </tr>'
# formats a month as a table
# filter jobs by year and month
def formatmonth(self, jobs, withyear=True):
cal = f'<table border="0" cellpadding="0" cellspacing="0" class="calendar table-responsive">\n'
cal += f'{self.formatmonthname(self.year, self.month, withyear=withyear)}\n'
cal += f'{self.formatweekheader()}\n'
for week in self.monthdays2calendar(self.year, self.month):
cal += f'{self.formatweek(week, jobs)}\n'
cal += f'</table>'
return cal
However, I'm not sure how I need to approach passing these days back into the formatday() method, or if I should be looking at a different way of doing it, as it all new to me, any help would be much appreciated.
Thanks

In your formatday function you can filter for jobs that are between start and end date (including those dates) by doing something like:
def formatday(self, day, jobs):
jobs_per_day = jobs.filter(start_time__day__gte=day, end_time__day__lte=day)
This will give you jobs that span any days from start to end including start and end. Then your current code will work to display a job on any day it spans. I believe this is what you were asking for, but feel free to clarify if not.

Related

Getting Datefield after Today and Before another date not returning the expected object

I am writing an app in Django where I have created a PayPeriods model as such:
class PayPeriods(models.Model):
first_day = models.DateField(default=date.today)
last_day = models.DateField(default=date.today)
pay_day = models.DateField(default=date.today)
I've created a small function that allows me to get the current PP through my app,
def get_pp():
_pp = PayPeriods.objects.filter(first_day__gte=datetime.today(),last_day__lt=datetime.today())[0]
return _pp
but its not returning as expected.
What am I missing?
Current day today is 11/29/2022, so I am expecting to return Obj #4, as the code is written.
PP Object #3: first_day = 11/13/22, last_day = 11/26/22
PP Ojbect #4: first_day = 11/17/22, last_day = 12/10/22
PP Ojbect #5: first_day = 12/11/22, last_day = 12/24/22
I have verified that my dates are formatted the same way, (stored data & datetime.today(), and my timezone settings are correct.).

Filtering ISO date by hour

I was trying to get the number of insurance claims by Day and what time it occurred. For Example, it is March 22 today and there were claims on 8 am another in 12noon. I was trying to get all the claim count this day and what hour did the claims occured.
I did try using modified_at__hour but it doesn't show what I needed.
Sample code for claims per week and show what day it was claimed
class GetClaimsCompare_week(APIView):
def get_claim_count(self, claims_data, claim_type):
claims_count = claims_data.filter(claim_type = claim_type).count()
return claims_count
def get_claims_type(self, claims_per_day):
return claims_per_day.claim_type
#return claims_data.claim_type
def get(self, request):
today = datetime.now()
claims_data = Claims.objects.filter(modified_at__day = today.day)
claims_per_day = claims_data.annotate(day = TruncDay('modified_at')).values('day').annotate(claim_type=Count('id'))
labels = []
claims_type = list(set(map(self.get_claims_type, claims_data)))
final = {}
for claims in claims_per_day:
labels.append(claims['day'])
#data.append(claims['claims'])
for claim_type in claims_type:
final[claim_type] = self.get_claim_count(claims_data, claim_type)
context = {
'Date(s)': labels,
'Claims on this date': final
}
return Response(context)

insert conditional for hours

Good evening, could you help me in how I can put a condition so that a message comes out saying that you can not take an hour because it is already busy ?, I currently have this:
class reserva (models.Model):
_name='gimnasio.reserva'
tipo_reserva=fields.Selection([('clase','Clase'),('evaluacion','Evaluacion')])
fecha_reserva=fields.Date()
start_time=fields.Float()
end_time=fields.Float()
def fecha(self):
if self.star_time==self.star_time:
raise validationError('the hour is busy')
I have another question for you. you know how to configure Datetime only for hour and minutes because I only need hour and minutes but not the date.
To configure Datetime only for hour and minutes.
time = fields.Datetime("time")
custom_time = fields.Char('my_custome_time')
#api.onchange('time')
def _get_time(self):
if self.time:
for rec in self:
# datetime value is a string like 'YYYY-mm-dd HH:MM:SS'
# so just extract string from position 11 to 16
_time = self.time[11:16]
self.custom_time = _time
rec.custom_time = self.custom_time
I think you can use strptime method from datetime module.
from datetime import datetime as dt
start_time = fields.Float()
end_time = fields.Float()
#api.onchange('start_time','end_time')
def _check(self):
records = self.env["gimnasio.reserva"].search([("day", '=', the day you want to check eg. "2019-06-13")])
for rec in records:
ref_start = dt.strptime(str(rec.start_time), "%H:%M")
curr_start = dt.strptime(str(self.start_time), "%H:%M")
if ref_start == curr_start:
raise validationError('the hour is busy')
I didn't debug yet, you can try it.
how to eliminate the default date that you added ("2019-06-13") and that any date should not have the same busy schedule?
In this case you don't need datetime module just
#api.constrains("start_time")
def _check(self):
# search db for any record have same start time.
records = self.env["gimnasio.reserva"].search([('start_time ','=', self.start_time)])
if len(records) > 0:
raise validationError('the hour is busy')

Check if any date in a range is between another range

I have the following situation:
This is my views.py:
def home(request):
date = datetime.date.today()
start_week = date - datetime.timedelta(date.weekday() + 1)
end_week = start_week + datetime.timedelta(6)
week_tasks = Task.object.filter(owner=request.user, start_date__range=[start_week, end_week])
context = {}
context['week_tasks'] = week_tasks
return render(request, 'home.html', context)
This view check if the start_date (DateField) is inside the range of the current week. But I have another field on the database, end_date, and I want to check if any value of this range is on the current week.
Check the exemple:
Let's supose that the current week is the week of the day 17. With my current view, only the All Day Event and Conference belong to the week. I need to show that all these events belong to the week.
Obs.: I can't just check if start_date and end_date are in the week, because I have the situation of the Long Event, that starts before the week and ends after.
WORKING:
views.py:
def home(request):
date = datetime.date.today()
if date.isoweekday() == 7:
date = date + datetime.timedelta(1)
start_week = date - datetime.timedelta(date.isoweekday())
end_week = start_week + datetime.timedelta(6)
week_tasks = Task.object.filter(owner=request.user).exclude(end_date__lt=start_week).exclude(start_date__gt=end_week)
context = {}
context['week_tasks'] = week_tasks
return render(request, 'home.html', context)
week window is defined by: week_start, week_end
tasks are defined by: task_start, task_end
task has overlap with week if:
task_start < week_end and task_end >= week_start

Reusing a Django RSS Feed for different Date Ranges

What would be a way to have date range based rss feeds in Django. For instance if I had the following type of django rss feed model.
from django.contrib.syndication.feeds import Feed
from myapp.models import *
class PopularFeed(Feed):
title = '%s : Latest SOLs' % settings.SITE_NAME
link = '/'
description = 'Latest entries to %s' % settings.SITE_NAME
def items(self):
return sol.objects.order_by('-date')
What would be a way to have PopularFeed used for All Time, Last Month, Last Week, Last 24 Hours, and vice-versa if I wanted to have LeastPopularFeed?
You need to define a class for each feed you want. For example for Last Month feed:
class LastMonthFeed(Feed):
def items(self):
ts = datetime.datetime.now() - datetime.timedelta(days=30)
return sol.object.filter(date__gte=ts).order_by('-date')
Then add these feeds to your urls.py as shown in docs: http://docs.djangoproject.com/en/1.2/ref/contrib/syndication/

Categories