Python Flask output dropdown values to page - python

I have a two dictionaries with several keys and one value for each key. One dict has weekly cumulative work hours, the other weekly cumulative overtime hours. The key is a datetime object, which is calculated to be the beginning of a week. On my webpage I have a dropdown box, which contains the week beginnings
<form action="{{ url_for('index') }}" method="post">
<select class="form-control" name="cumuls" id="select1" onchange="if(this.value != 0) { this.form.submit(); }">
<option value="0">Cumulative for week beginning...</option>
{% for i,j in zip(wks, wks2) %}
<option value="{{ i }}">{{ j }}</option>
{% endfor %}
</select>
</form>
(wks2 is just a nicely formatted version of wks, and wks is just a list of the keys from the dicts which are datetime objects (the dictionaries have the same keys))
I want to be able to click on an option from the dropdown box and for the corresponding values from the two dictionaries to appear below the dropdown box.
I handle the form here (within an index() function), after the if is the end of the index function:
if request.method == 'POST':
if 'cumuls' in request.form:
week_Begin = request.form['cumuls']
listHours = listDates(current_user.get_id())
dct_hours, dct_overtime, wks = weeklySum2(listHours)
#strfdelta is a custom function that formats timedeltas
cumul_hrs = strfdelta(dct_hours[datetime.fromisoformat(week_Begin)], '%H:%M')
cumul_overtime = strfdelta(dct_overtime[datetime.fromisoformat(week_Begin)], '%H:%M')
return redirect(url_for('index'))
listHours = listDates(current_user.get_id())
dct_hours, dct_overtime, wks = weeklySum2(listHours)
print(wks)
# wkbgn = weekbeginning, this just formats the dates nicely
wks2 = [wkbgn.strftime('%A') + ' ' + wkbgn.strftime('%-d') + ' ' + wkbgn.strftime('%b') + ' ' + wkbgn.strftime('%Y') for wkbgn in wks]
currentDay = datetime.today()
start_week = (currentDay - timedelta(days=currentDay.weekday()))
return render_template('index.html', form=form, hoursDb = listHours, dct_overtime=dct_overtime,dct_hours=dct_hours, wks=wks, wks2=wks2, zip=zip)
So within the if 'cumuls'..., I basically get the cumulative working and overtime hours for the selected week, in cumul_hrs and cumul_overtime, which works. I essentially want these variables to be displayed on the webpage (below the dropdown box), and the default variable that is displayed will be the current weeks cumulative so far. How could I do this?
Any pointers/tips are greatly appreciated.

I ended up just changing the redirect within the elif statement to
return redirect(url_for('index', cumul_hrs=cumul_hrs, cumul_overtime=cumul_overtime))
and then getting the variables from the URL with:
cumul_hrs, cumul_overtime = request.args.get('cumul_hrs'), request.args.get('cumul_overtime')
and passing them through render_template.

Related

Increment Last Id from String in python Django

I am trying to generate an auto-increment number as an ID with Company Label. Company Labels will be changing for every user. So I cant use slicing here.
My ID is like TES-PRODUCT-01
TES is a company label
PRODUCT is as it is name
But now I wish to change my last number when I am adding new product to TES-PRODUCT-02 and so on
Getting Error **can only concatenate str (not "int") to str**
Here is my code
views.py
def add_new_stock(request):
stock_data=New_Stock_Entry.objects.all()
if not stock_data:
latest_item_code="TES-PRODUCT-001"
else:
latest_item_code = (New_Stock_Entry.objects.last()).item_code+1
get_tax_code=Tax_Settings.objects.values('name', 'tax_percentage','tax_id')
if request.method == 'POST':
item = request.POST['item']
hsn = request.POST['hsn']
item_code=latest_item_code
stock_in_date=request.POST['stock_in_date']
quantity_in_hand=request.POST['quantity_in_hand']
sales_price=request.POST['sales_price']
item_description=request.POST['item_description']
unit=request.POST['unit']
tax_code = request.POST['tax_code']
tax_obj = Tax_Settings.objects.get(tax_id=tax_code)
item_creation_details = New_Stock_Entry.objects.create(item=item, hsn=hsn, item_code=item_code,stock_in_date=stock_in_date,quantity_in_hand=quantity_in_hand,sales_price=sales_price ,item_description=item_description, unit=unit, tax_code=tax_obj)
item_creation_details.save()
print("item_details",item_creation_details)
return render(request,"inventory/add-stock.html")
return render(request,"inventory/add-stock.html",{'get_tax':get_tax_code,'latest_item_code':latest_item_code})
html
<input type="text" class="form-control" placeholder="TES-PRODUCT-{{latest_item_code}}" name="item_code">
How Can I increment my last number from string?
You can simply use "f-strings"
total_stock = New_Stock_Entry.objects.all().count() + 1
latest_item_code=f"TES-PRODUCT-{total_stock}"

Passing list dict to template not working django

I am trying to pass a list called eligable so that I can display on my website but when I run my website it does not display the list. I do not understand what is wrong.
code:
def specificDate(response):
empName = employeeName.objects.all()
eligable = []
if 'checkEmployee' in response.POST:
n = response.POST.get("nameEmployee")
specDate = response.POST.get("date")
if employeeName.objects.filter(employee=n).exists() and Name.objects.filter(date=specDate).exists():
emp = employeeName.objects.get(employee=n)
t = Name.objects.get(name=emp, date=specDate)
overT = Name.objects.filter(name=emp, overtime=True)
for item in overT:
eligable.append(item.date)
checkIn = t.timeIn.strftime("%H:%M:%S")
checkOut = t.timeOut.strftime("%H:%M:%S")
datee = datetime.strptime(specDate,'%Y-%m-%d')
print("Here:: ",t.date)
print("Month:: ",datee.month)
messages.info(response, checkIn + ' - ' + checkOut)
return redirect('/specificDate')
else:
messages.info(response, 'Name does not exist')
else:
pass
return render(response, "main/specificDate.html", context={"empName":empName, "eligable":eligable})
This is the html to print my list:
{% for item in eligable %}
<div class="pad3">
{{item}}
</div>
{% endfor %}
There are two return statements in your code:
return redirect('/specificDate')
and
return render(response, "main/specificDate.html", context={"empName":empName, "eligable":eligable})
The first one is just redirecting without populating context.
The second one does populate context but is reached only when eligable is empty.
I think changing the first return to the second one should solve it.
edit: and you are missing {% endfor %} here. But it should give you an error if you miss it in your complete code.

List index is out of range when passing empty values

Okay so I have the following HTML form:
<form method ="post" action="/custom">
<div class="container">
<select multiple name ="multiple">
<option value="id">ID</option>
<option value="is_visible">Visible</option>
</select>
<button type="submit">Login</button>
</div>
</form>
And I have the following Python code to insert values in to the database
#app.route('/custom',methods = ['POST', 'GET'])
def custom_fields():
login = 'urlhere.com'
url_tags = 'targeturlhere.com/page.json'
multiple = request.form.getlist('multiple')
post = session.post(login, data=payload)
r_tags = session.get(url_tags)
parsed_tags = json.loads(r_tags.text)
for tag in parsed_tags['tags']:
cursor.execute("INSERT INTO dbo.tags"
"(tagid, is_visible, products_count, slug, title, created_at ,updated_at )"
"VALUES (?,?,?,?,?,?,?)"
,(tag[multiple[0]],tag[multiple[1]], tag['products_count']
,tag['slug'],tag['title'],tag['created_at'],tag['updated_at']))
con.commit()
So what I do now is to select the values that I want to pass to the Python code. My problem now is that if I choose the values that the code is working, but if I don't choose something I get the following:
IndexError: list index out of range
Is there any possible way to pass empty values and to accomplish what I want? Also note that I am working with json code, see a format below:
{
tags: [
{
created_at: "2018-02-28T14:55:19+01:00",
customer_id: null,
id: 4544544,
is_visible: true,
products_count: 6,
slug: "productname",
title: "productname",
updated_at: "2018-05-25T00:08:04+02:00"
},
],
}
I'm assuming you are passing an empty value for the multiple key. The simplest solution would be to check the contents of the multiple list right after taking it from the request. If it is empty, use a default one:
multiple = request.form.getlist('multiple')
if not multiple or len(multiple) < 2:
multiple = ['default_tag', 'default_is_visible']

Why do my dates and times differ?

I have in my jinja2 template code for localization.
{% set currency = "SEK" %}
{% set format = "sv_SE" %}
{% set timezoneinfo = 'Europe/Stockholm' %}
{% set locale = "se" %}
But it's not working for hours and minutes if I use it like this with a filter using values from a google search API result to filter.
{{scored_document.fields.10.value|datetimeformat_list(hour=scored_document.fields.17.value|int ,minute =scored_document.fields.18.value|int, timezoneinfo=timezoneinfo, locale=locale)}}
filter
def datetimeformat_list(date, hour, minute, locale='en', timezoneinfo='Asia/Calcutta'):
tzinfo = timezone(timezoneinfo)
input = datetime(date.year, date.month, date.day, int(hour), int(minute), tzinfo=tzinfo)
time_str = format_time(input, 'H:mm', tzinfo=tzinfo, locale=locale)
return "{0}".format(time_str)
The code gives a different time than if I just do
{{ ad.modified|datetimeformat_viewad(locale='se', timezoneinfo='Europe/Stockholm') }}
with this filter
def datetimeformat_viewad(to_format, locale='en', timezoneinfo='Asia/Calcutta'):
tzinfo = timezone(timezoneinfo)
month = MONTHS[to_format.month - 1]
date_str = '{0} {1}'.format(to_format.day, _(month))
time_str = format_time(to_format, 'H:mm', tzinfo=tzinfo, locale=locale)
return "{0} {1}".format(date_str, time_str)
Why are the outputs not the same time?
It is incorrect to pass an arbitrary pytz timezone to datetime constructor directly; you should use pytz_tzinfo.localize() method instead as it is said at the very beginning of pytz docs.
There could be other issues in your code.

Add one day in time from database in django

Hi,
I need to add some condition on the time base , right now the value of time i am getting from database is like 2012-09-05 05:05:05 and i need to add 24 hours in this.
I need to show different content on time base, like for original time i need to show "hi" and after 24 hours i need to show "hello" in the template file.
How can i do this? Please help me.
probably a custom template tag would be a nice way: https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#writing-custom-template-filters . you could implement your own deltaDays tag with parameters, i.e. {{ date|deltaDays:1 }}.
You could also do this as a cheap filter.
from django import template
register = template.Library()
#register.filter()
def is_at_least_24_hours_ago(value):
import datetime
original_date_plus_24 = value + datetime.timedelta(hours=24)
right_now = datetime.datetime.now()
if right_now >= original_date_plus_24:
return True
return False
Then in your template:
{% if object_date|is_at_least_24_hours_ago %}
// It's 24 hours later
{% else %}
// It's not
{% endif %}
This is sample on how to add day(s),
import datetime
b = var_name + datetime.timedelta(0,3) # days, seconds
or
datetime.timedelta(days=1)
pass the value through view then use if statement in your template

Categories