I new with python and django, currently I little a bit confused about how to do my project.
Scenario is simple:
User by using form on fronted is requested weekly statistic of customers and should get list of statistic per customer on selected period (year, week)
So far I able to query data from raw database, function for count statistic start_date and end_date of selected week working fine.
in my models.py
def WeekRange(year, week):
d = date(year, 1, 1)
delta_days = d.isoweekday() - 1
delta_weeks = week
if year == d.isocalendar()[0]:
delta_weeks -= 1
delta = timedelta(days=-delta_days, weeks=delta_weeks)
weekbeg = datetime.datetime.combine(d, datetime.time(00, 00, 01)) + delta
delta2 = timedelta(days=6-delta_days, weeks=delta_weeks)
weekend = datetime.datetime.combine(d, datetime.time(23, 59, 59)) + delta2
cursor = connections['nocdb'].cursor()
cursor.execute("SELECT DISTINCT (p.name) AS platform, count(e.id ) AS count FROM event e, lu_platform p WHERE e.platform_id = p.id AND e.sourcetype_id = 1 AND e.event_datetime BETWEEN %s AND %s AND e.sender_id NOT IN ( 759, 73 ) GROUP BY p.name ORDER BY p.name", [weekbeg, weekend] )
results = cursor.fetchall()
return results
view.py
def WeekRequestForm(request):
form = WeekSelection()
year = request.POST.get("q_year", "")
week = request.POST.get("q_week", "")
currstat_b = [year, week]
weekstat = WeekRange(*currstat_b)
return render_to_response('form.html', {'weekstat': weekstat, 'form': form}, context_instance=RequestContext(request))
forms.py
YEARCHOICE = tuple((str(n), str(n)) for n in range(2011, datetime.now().year + 1))
WEEKCHOICE = range(1, 53)
class WeekSelection(forms.Form):
q_year = forms.ChoiceField(label='Year', choices=YEARCHOICE, initial=(datetime.today().isocalendar()[0]))
q_week = forms.ChoiceField(label='Week', choices=zip(WEEKCHOICE, WEEKCHOICE), initial=(datetime.today().isocalendar()[1]))
With followings I get "an integer is required"
after replace currstat_b = [2013, 48] everything working fine and show me statistick of week 48.
Problem is how to get selected numbers from form to argument in weekstat = WeekRange(*currstat_b)
Also I not sure if is better put raw data function in views or in models as is now.
I will be appreciated for any tip
Maybe passing data through form could help, try this:
def WeekRequestForm(request):
form = WeekSelection()
weekstat = None
if request.method == "POST":
form = WeekSelection(request.POST)
if form.is_valid():
year = int(form.cleaned_data["q_year"])
week = int(form.cleaned_data["q_week"])
currstat_b = [year, week]
weekstat = WeekRange(*currstat_b)
return render_to_response('form.html', {'weekstat': weekstat, 'form': form},
context_instance=RequestContext(request))
Related
I am using calendar on my server. The current day should be marked but it is not refreshing it. As a result, marked day is the day of server restart. Do you have any solution to this issue? I want it to mark correct day, not the day on which server occurred. Thanks for help.
UPDATE
This is the code i use
This is entire view function
today = datetime.datetime.today()
#pulling models from database
employee = Employee.objects.filter(barberName=Barber)
reservations = Appointments.objects.all()
apptDict = {}
timeList = []
#make list of all possible appointments for the day
for x in employee:
startTime = "28/02/22 " + str(x.barberStartTime)
endTime = "28/02/22 " + str(x.barberEndTime)
startTimeObj = datetime.datetime.strptime(startTime, '%d/%m/%y %H:%M:%S')
endTimeObj = datetime.datetime.strptime(endTime, '%d/%m/%y %H:%M:%S')
while startTimeObj < endTimeObj:
justTimeList = str(startTimeObj).split(" ")[1].split(":")
timeList.append(justTimeList[0] + ":" + justTimeList[1])
startTimeObj += datetime.timedelta(hours=0.5)
apptDict["possibleTimes"] = timeList
#make dictionary of already made appointments in form "date": ["time1", "time2", "timeN"]
for reservation in reservations:
time = str(reservation.time).split(":")
timeStr = time[0] + ":" + time[1]
if str(reservation.date) not in apptDict:
apptDict[str(reservation.date)] = []
apptDict[str(reservation.date)].append(str(timeStr))
if reservation.date < today.date():
apptDict[str(reservation.date)] = ["Over"]
#write to json file
with open("reservations/static/reservations/scripts/appointments.json", "w") as outfile:
json_object = json.dumps(apptDict, indent=4)
outfile.write(json_object)
context = {
"place": Place,
"barber": Barber,
"service": Service,
"calendar": newCalendar(datetime.datetime.today().month, datetime.datetime.today().year, Barber),
"employee": employee,
"availableTimes": timeList,
"apptDict": apptDict,
"availTimes": timeList
}
if request.method == "POST":
postCopy = request.POST.copy()
postCopy['time'] = datetime.datetime.strptime('15/05/22 ' + postCopy['time'], '%d/%m/%y %H:%M').time()
postCopy['phone'] = str(postCopy['phone'])
request.POST = postCopy
form = AppointmentForm(request.POST or NONE)
if form.is_valid():
form.save()
return render(request, 'reservations/reserved.html', context)
return render(request, 'reservations/reservationTime.html', context)
This is the part of calendar function. It is supposed to visually mark previous days
for x in range(1, int(today.day)):
cal = cal.replace(">" + str(x) + "<", 'style="color: #808080;">' + str(x) + "<") #marking previous days in month
I want to add all the amount field during a date range query search. I have an Income Model with date and amount fields among others. And any time a user select between two dates, I want the amount fields of the query results added as total.
Here is what I have tried:
def SearchIncomeRange(request):
listIncome = Income.objects.all()
searchForm = IncomeSearchForm(request.POST or None)
if request.method == 'POST':
listIncome = Income.objects.filter(
description__icontains=searchForm['description'].value(),
date__range=[
searchForm['start_date'].value(),
searchForm['end_date'].value()
]
)
else:
searchForm = IncomeSearchForm()
paginator = Paginator(listIncome, 5)
page = request.GET.get('page')
paged_income = paginator.get_page(page)
context = {
'searchForm':searchForm,
}
return render(request, 'cashier/search_income_range.html', context)
I am able to get the correct search result but getting the total I don't know how to use the SUM in the above query and pass the total in pagination. So Someone should please help me out. Thanks
from django.db.models import Sum
total_amount = listIncome.aggregate(total=Sum('amount'))
where listIncome is your queryset
Edit:
You should pass queryset in pagination with filtered queryset if any filter you apply.
I changed your written code but you can write this code in a good way.
def SearchIncomeRange(request):
listIncome = Income.objects.all()
searchForm = IncomeSearchForm(request.POST or None)
if request.method == 'POST':
# you can get filter value by your form data
post_data = request.POST
description = post_data['description']
start_date = post_data['start_date']
end_date = post_data['end_date']
else:
# you can get filter value by your query params
query_params = request.GET
description = query_params.get('description')
start_date = query_params.get('start_date')
end_date = query_params.get('end_date')
# Apply filter before pagination
listIncome = listIncome.filter(
description__icontains=description,
date__range=[start_date, end_date]
)
# calculate total_amount
total_amount = listIncome.aggregate(total=Sum('amount'))
paginator = Paginator(listIncome, 5)
page = request.GET.get('page')
paged_income = paginator.get_page(page)
# you can access total_amount in template by passing in context data
context = {
'searchForm':searchForm,
'total_amount': total_amount
}
return render(request, 'cashier/search_income_range.html', context)
I am trying to get third button to work on a simple app I am making. I set up if statements to detect the value of the request for two buttons, but I am getting stuck on how to configure the logic statement to get a third parameter through.
My issue is that I need to have the form filled with any data before the subscriptions button will work properly. When the form is blank the app will indicate the form needs to be filled out. I am not familiar with javascript to have the buttons run from that. My hope is that I can learn how to configure the if statement to have the subscriptions call work without the form being filled out.
Below is the UI as and the views.py def. The Amount and Delete functions work fine. It is just the subscription button that won't work until I put literally any data into the two text fields fields.
def usage(request):
if request.method == 'POST':
form = UsageForm(request.POST)
if form.is_valid():
if request.POST.get('subscription') == 'Subscription':
dt = datetime.today()
month = dt.month
year = dt.year
day = calendar.monthrange(year, month)[1]
eom = str(month) + "/" + str(day) + "/" + str(year)
anchor = int(time.mktime(datetime.strptime(eom, "%m/%d/%Y").timetuple()) + 68400)
cust_list = json.loads(str(stripe.Customer.list(limit=100)))
for item in cust_list['data']:
try:
print(item['subscriptions']['data'][0]['id'], item['email'], item['id'])
except:
stripe.Subscription.create(
customer=item['id'],
items=[{'plan': 'plan_DFnNVzXKJ2w0Ad'}],
billing_cycle_anchor=anchor,
)
if request.POST.get('delete') == 'Delete':
cust_info = custinfo.objects.all()
cust_info.delete()
all_custinfo_items = custinfo.objects.all()
else:
Sub_ID = form.cleaned_data['Sub_ID']
amount = form.cleaned_data['amount']
stripe_data = stripe.SubscriptionItem.list(subscription=Sub_ID)
sub_item = stripe_data["data"][0]["id"]
stripe.UsageRecord.create(
quantity=amount,
timestamp=int(time.time()),
subscription_item=sub_item,
action='increment')
form.save()
print("Last Ran: ", Sub_ID, amount)
all_custinfo_items = custinfo.objects.all()
return render(request, 'form.html', {'form': form, 'custinfo_items': all_custinfo_items})
else:
form = UsageForm()
# all_subid_items = custinfo.objects.filter(Sub_ID__startswith='sub')
return render(request, 'form.html', {'form': form})
I am trying to increment my DB by 1 if a user has not visited that unique item.pk before. At the moment it will only increment by 1 for all items in my DB, id like to to increment by 1 for each item.pk in the DB.
The view is to Create a view that returns a single bug object based on the bug ID (pk) and render it to the bug_detail.html template or return 404 error if object is not found Also handles commenting on the bug as well as regulating the amount of views attributed to the bug.
def bug_detail(request, pk):
bug = get_object_or_404(Bug, pk=pk)
if request.method == "POST":
form = BugCommentForm(request.POST)
if form.is_valid():
bugComment = form.save(commit=False)
bugComment.bug = bug
bugComment.author = request.user
bug.comment_number += 1
bug.save()
bugComment.save()
return redirect(reverse('bug_detail', kwargs={'pk': pk}))
else:
messages.error(
request,
"Looks like your comment is empty!",
extra_tags="alert-danger")
form = BugCommentForm(instance=bug)
return redirect(reverse('bug_detail', kwargs={'pk': pk}))
else:
form = BugCommentForm()
comments = BugComment.objects.filter(bug__pk=bug.pk)
comments_total = len(comments)
response = render(request,
'bug_detail.html',
{'bug': bug,
'comments': comments,
'comments_total': comments_total,
'form': form})
if 'last_visit' in request.COOKIES and 'bugg' in request.COOKIES:
last_visit = request.COOKIES['last_visit']
# the cookie is a string - convert back to a datetime type
last_visit_time = datetime.strptime(
last_visit[:-7], "%Y-%m-%d %H:%M:%S")
curr_time = datetime.now()
if (curr_time - last_visit_time).days > 0:
# if at least one day has gone by then inc the views count.
response.set_cookie('last_visit', datetime.now())
bug.views += 1
bug.save()
elif 'bugg' not in request.COOKIES:
response.set_cookie('last_visit', datetime.now())
response.set_cookie('bugg', bug.pk)
bug.views += 1
bug.save()
else:
response.set_cookie('last_visit', datetime.now())
response.set_cookie('bugg', bug.pk)
bug.views += 1
bug.save()
return response
I have a form that accepts a single date, or a date range. The date is then passed to a subsequent view that queries the DB and produces a result. I've managed to pass the single date via the URL
but I have yet to find a means to pass the date range from the form to the subsequent view where the query is run.
( Note: I understand that the indentation of the form presented below is off. For some this is my first post and I'm not yet wise to all the subtleties of stack overflow)
class Date_rangeFRM(forms.Form):
Single_date = forms.DateField(required=False)
Date_start = forms.DateField(required=False)
Date_end = forms.DateField(required=False)
def date_range(request):
context = RequestContext(request)
if request.method == 'POST':
form = Date_rangeFRM(request.POST)
print "valid", form.is_valid()
print "form", str(form)
if form.is_valid():
#print "form", str(form)
Single_date = form.cleaned_data['Single_date']
Date_start = form.cleaned_data['Date_start']
Date_end = form.cleaned_data['Date_end']
if Single_date != "":
#print "redirecting to Dav View:", '/counter/%02d-%02d-%02d/Day_view/' %(Single_date.year,Single_date.month,Single_date.day)
return HttpResponseRedirect('/counter/%02d-%02d-%02d/Day_view/' %(Single_date.year,Single_date.month,Single_date.day))
else:
#****passing Magic ********
return HttpResponseRedirect('/counter/History_View/')
else:
print form.errors
else:
form = Date_rangeFRM()
return render_to_response('counter/historyFRM.html', {'form':form}, context)
def History_View(request):
context = RequestContext(request)
#****** Receiving magic********
date_start = form.cleaned_data['date_start']
date_end = form.cleaned_data['date_end']
context['meal_list'] = meal_list
context['comp_list'] = comp_list
context['day_list'] = day_list
dt_range = []
day_list = RecordedDays.objects.filter(profile= request.user.userprofile,
Date__gte = date_start, Date__lte = date_end )
for day in day_list:
dt_range.append(day.Date)
meal_list = MealType.objects.filter(
newDay__profile = request.user.userprofile,
newDay__Date__gte = date_start, newDay__Date__lte = date_end )
#newDay__Date= date( int(year), int(month), int(day) ) )
for meal in meal_list:
dt_range.append([ meal.get_mealNum_display(), meal.Mealtotal() ])
comp_list =Ingredient.objects.filter(numMeal = meal)
for comp in comp_list:
dt_range[-1].append([comp.component, comp.comp_total()] )
return render_to_response('counter/history_view.html', context
Also I'm not entirely sure I'm using the __lte, __gte feature correctly. If you could please inspect it. Much appreciated.
Thanks One and all for your Help.