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
Related
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.).
I need to make object selections in my database by time interval
currently i found a method to select only objects from a day but not from an interval with this:
data.filter(end_at__day=datetime.datetime.now().day)
I saw this on the django __gte documentation which means from a date until today but I failed to make it work
I have try this:
if request.method == 'POST':
form = DashboardSettingsForm(data=request.POST)
if form.is_valid():
dis_planned = form.cleaned_data.get('display_planned')
dis_currently = form.cleaned_data.get('display_currently')
dis_ended = form.cleaned_data.get('display_ended')
end_at = start_at = datetime.now()
if dis_ended:
end_at = datetime.now() - timedelta(hours=12)
if dis_planned:
start_at = datetime.now() + timedelta(hours=12)
data = data.filter(start_at__gt=start_at, end_at__gt=end_at)
print(f"interval: start{start_at} end{end_at}")
data = data.filter(start_at__gt=start_at, end_at__gt=end_at)
The above line means the objects need to satisfy:
start_ats that are later than datetime.now() - timedelta(hours=12)
end_ats that are later than datetime.now() + timedelta(hours=12)
So you need to use the reverse (lt) for end_at, to make it a filter that covers a range within:
data = data.filter(start_at__gt=start_at, end_at__lt=end_at)
This essentially means the objects need to meet this criteria:
start_ats that are later than datetime.now() - timedelta(hours=12)
end_ats that are earlier than datetime.now() + timedelta(hours=12)
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)
i make a reservation system, which has form validation,
This should check whether the the bus on that date is already booked or not,
but, unfortunately there still error on this code..
so here my code :
forms.py
class BookingForm(forms.ModelForm):
class Meta:
model = Booking
fields = '__all__'
tempReDate = date(1,1,1) # temp local variable
def clean_start(self):
start = self.cleaned_data['start']
# cheacking if date for this bus is free
res_all = Booking.objects.all()
for item in res_all:
if start >= item.start and start <= item.end and item.resourceId == self.instance.resourceId:
raise forms.ValidationError("This date already reserved by same bus, choose other date or other bus")
#set variable to send for next funtion: clean_EndDate
self.tempReDate = start
return start
def clean_end(self):
#check if EndDate is empty
if not self.data['end']:
#set numbers days of reservation 1 if no end date
self.instance.numOfDays = 1
return None
# if start date is empty
if self.tempReDate == date(1,1,1):
raise forms.ValidationError("Must Choose start date")
# if start date is not empty
else:
start = self.tempReDate
end = self.cleaned_data['end']
# cheackig start date is not lower than end date
if end < start:
raise forms.ValidationError("start date cannot be later than end date")
# cheackig if reservation is no longer than 14 days
if end > start+ timedelta(days=14):
raise forms.ValidationError("You can make a reservation for max 14 days")
# cheacking if reservation for this bus is free
res_all = Booking.objects.all().filter(resourceId=self.instance.resourceId)
for item in res_all:
#jesli w przedziale nowego zamowienia jest poczatek albo koniec innego to zajęte
if start <= item.start and item.start <= end or start <= item.end and item.end <= end:
raise forms.ValidationError("This date already reserved by same bus, choose other date or other bus")
# calculateing number days of reservation and save it
var = end - start
self.instance.numOfDays = var.days + 1
return start
And this code on views.py
views.py
def create_book(request):
booking_forms = BookingForm()
customer_forms = CustomerForm()
if request.method == 'POST':
booking_forms = BookingForm(request.POST)
customer_forms = CustomerForm(request.POST)
if customer_forms.is_valid() and booking_forms.is_valid():
nama_pelanggan = customer_forms.cleaned_data['nama_pelanggan']
no_hp = customer_forms.cleaned_data['no_hp']
# nmpl = request.POST['nama_pelanggan']
# nm_pl = {"nama_pelanggan": nmpl}
customer, _ = Customer.objects.get_or_create(no_hp=customer_forms.cleaned_data['no_hp'],
defaults={
'nama_pelanggan': customer_forms.cleaned_data['nama_pelanggan'],
'alamat_pelanggan': '',
'tipe': ''
},)
idbooking = booking_forms.cleaned_data['idbooking']
resourceId = booking_forms.cleaned_data['resourceId']
start = booking_forms.cleaned_data['start']
end = booking_forms.cleaned_data['end']
harga_jual = booking_forms.cleaned_data['harga_jual']
uang_jalan = booking_forms.cleaned_data['uang_jalan']
parkir_bensin = booking_forms.cleaned_data['parkir_bensin']
note = booking_forms.cleaned_data['note']
Booking.objects.create(
idbooking=idbooking,
resourceId=resourceId,
start=start,
end=end,
harga_jual=harga_jual,
uang_jalan=uang_jalan,
parkir_bensin=parkir_bensin,
note=note,
title=resourceId,
nm_pelanggan=nama_pelanggan,
backgroundColor='blue'
),
return redirect('booking-list')
else:
print(booking_forms.errors)
print(customer_forms.errors)
context = {
'cform': customer_forms,
'form': booking_forms,
}
return render(request, 'booking/create_book.html', context)
What error ?
The problem im facing now, when i make reservation use same bus on same date, the validation error message not showing, and program continue make booking which is make double booking and will make conflict
.
what is problem with this form validation ?
.
thanks
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.