Error statement on Django and Python web development - python

I've one problem here on elif statement.
time and visual are my checkbox value.Click here for more understanding
On if statement is working if user select visual in checkbox it will display the output that I read from text file.
When comes to elif statement if check only time it will display nothing
I want user to have an option want to display the first statement, second statement or both of it
THIS views.py
token = request.GET.get('token')
context = {}
data = {}
prev_key = ''
with open(path) as input_data:
for line in input_data:
if (token == 'visual'):
if line.startswith('2_visualid_')
prev_key = line.lstrip('2_visualid_').rstrip()
data.update({line.lstrip('2_visualid_').rstrip(): []})
elif (token == 'time'):
if search_string in line:
if prev_key in data:
data[prev_key].append
(next(input_data).lstrip('2_mrslt_').rstrip())
context = {'output': data}
return render(request, 'Output.html', context)
Form HTML
<form action="">
&nbsp&nbsp<input class="regular-checkbox" type="checkbox" name="token" value="visual"><b>&nbsp&nbsp Visual ID</b><br>
&nbsp&nbsp<input class="regular-checkbox" type="checkbox" name="token" value="time"><b>&nbsp&nbsp Time Delay Index</b>
</form>
Note
Hope you can understand be pleased to comment on my explanation don't just downvote it because I learn nothing from it. Thank you.

Ok your problem is that 1. you're only retrieving one single value for the token key (HTTP querystrings and forms can have multiple values for a same key) and 2. you're only testing against one single value.
The first problem is easily solved by using request.GET.getlist("token") to get all values (instead of only the last one), as documented here.
The second problem is easily solved too: now that you have a list instead of a single value, just test for containmenent (if xxx in values) instead of equality (if value == xxx) and replace the elif with a if:
tokens = request.GET.getlist('token')
# ...
with open(path) as input_data:
for line in input_data:
if 'visual' in tokens and line.startswith('2_visualid_'):
prev_key = line.lstrip('2_visualid_').rstrip()
data.update({prevkey: []})
# you may want to continue to next line here - or not
# continue
if 'time' in tokens:
if search_string in line and prev_key in data:
data[prev_key].append(next(input_data).lstrip('2_mrslt_').rstrip())

Related

can't display the line by line converted list on the webpage using python

this the first function that returns the list:
def getListOfKeyWord(keyword):
df=pd.read_excel('finaltrue.xlsx')
corpus=[]
for i in range(len(df)):
if keyword in df["text"][i]:
corpus.append(df["text"][i])
return corpus
this the function where i printing the list as line by line:
def listing(result):
x=0
for item in range(0,len(result)):
x+=1
table = print(x,"",result[item])
return table
this is the placeholder in html :
<div class="row center">
{{key}}
</div>
and here where i call the functions at the app.routing
if request.method=='POST':
word = request.form['kword']
result=getListOfKeyWord(word)
table=listing(result)
return render_template('advance_search.html',key=table)
return render_template('advance_search.html')
now i get a "none" word at the placeholder position
can anyone help please ?
First of all, you cannot assign the output of print() function to a variable.
The key issue here is your listing function. You can use this code instead:
def listing(result):
table = '<br>'.join([ f'{i+1}- {item}' for i, item in enumerate(result) ])
print(table)
return table
You need to use <br> instead of \n to join the list since HTML will show <br> as new line, not \n.

no printing inside of "if" block

I have the code below in my juniper book. If user_payments is empty, i have message "no information" back. it works fine. But if rent_id is not empty, the information about user_profile (which must be printed inside of if: block, is not visible.
If I add printing user_profile after if-else block and information is exist - it shows correctly.
if not user_payments.loc[:,'powerBankRentId'].empty:
rent_id = user_payments.loc[:,'powerBankRentId'].values[0]
user_profile['rent_id'] = rent_id
user_last_rent = table_rents[table_rents['id'] == rent_id]
user_profile.append(table_rents[table_rents['id'] == rent_id].loc[:,['station_name','createdAt','endAt']])
user_profile['station_name'] = user_last_rent.loc[:,'station_name'].values[0]
user_profile['start_rent'] = user_last_rent.loc[:,'createdAt'].values[0]
user_profile['end_rent'] = user_last_rent.loc[:,'endAt'].values[0]
user_profile # doesn't print anything
else:
print('no information')
Can you give me an idea how i mush correct the code?
as it is one row dataframe, i wrote:
user_profile.head
and got expected

Sending a form array to Flask

I have an HTML form with multiple inputs named like this:
<input name="hello[]" type="text" />
<input name="hello[]" type="text" />
<input name="hello[]" type="text" />
In PHP you get this as an array but is it the same way in Python, using Flask?
I have tried this:
hello = request.form['hello']
print(hello)
But that did not work, I got a 400 Bad Request:
Bad Request
The browser (or proxy) sent a request that this server could not understand.
How do I do it in Flask?
You are following a PHP convention of adding brackets to the field names. It's not a web standard, but because PHP supports it out of the box it is popular; Ruby on Rails also uses it.
If you do use that convention, to get the POST data on the Flask side you need to include the square brackets in the field name. You can retrieve all values of the list using MultiDict.getlist():
hello = request.form.getlist('hello[]')
You don't have to use the [] convention at all, of course. Not appending the [] to the hello name will work perfectly fine, at which point you'd use request.form.getlist('hello') in Flask.
I written a parse function which supports multidimensional dict:php_post=parse_multi_form(request.form)
def parse_multi_form(form):
data = {}
for url_k in form:
v = form[url_k]
ks = []
while url_k:
if '[' in url_k:
k, r = url_k.split('[', 1)
ks.append(k)
if r[0] == ']':
ks.append('')
url_k = r.replace(']', '', 1)
else:
ks.append(url_k)
break
sub_data = data
for i, k in enumerate(ks):
if k.isdigit():
k = int(k)
if i+1 < len(ks):
if not isinstance(sub_data, dict):
break
if k in sub_data:
sub_data = sub_data[k]
else:
sub_data[k] = {}
sub_data = sub_data[k]
else:
if isinstance(sub_data, dict):
sub_data[k] = v
return data
Usage:
>>> request.form={"a[0][name]": "ahui", "a[0][sex]": "female", "a[1][name]": "bhui", "a[1][sex]": "male"}
>>> parse_multi_form(request.form)
{'a': {0: {'name': 'ahui', 'sex': 'female'}, 1: {'name': 'bhui', 'sex': 'male'}}}
Warnning: It does not support list,e.g. a[][0]=1&a[][0]=2, it may make programmer to be confused.
Either a=[[1,2]] or a[[1],[2]] is too hard to choose.
So I suggest use dict to replace list:
<input name="hello[0]" type="text" />
<input name="hello[1]" type="text" />
If you still want to post complex data, I suggest you use application/json
I have a form that has arrays with either one or two levels, so either a[1] or b[1][2].
I've written a regex solution to get this into the dict with posted data.
import re
re_post = re.compile(r'([a-z_]*)(\[(.*?)\])?(\[(.*?)\])?')
for post_key, post_value in request.form.copy().items():
matches = list(re_post.findall(post_key)[0][0::2])
if matches[1]:
request.form.setdefault(matches[0], {})
if matches[2]:
request.form[matches[0]].setdefault(matches[1], {})
request.form[matches[0]][matches[1]][matches[2]] = post_value
else:
request.form[matches[0]][matches[1]] = post_value
else:
continue
del request.form[post_key]
So it iterates over the form keys/values and matches 3 groups in the key: first the 'base' name, and then the names of two levels. If either first or second level name is present, it will create a dictionary and populate it with the posted value and then proceeds to remove the original key/value.

storing original upload filename (web2py)

I'm attempting to do something simple and documented well, except for that it's not working on my web app.
essentally i want to save some extra attributes for the uploaded files, like original filename, email of user and also the upload date.
Now following the web2py documentation i've created this submit view. It is almost word for word copied from the documentation section here
I have a controller data.py
def submit():
import datetime
form = SQLFORM(db.uploads, fields=['up_file'], deletable=True)
form.vars.up_date = datetime.datetime.now()
form.vars.username = auth.user.email
if request.vars.up_file != None:
form.vars.filename = request.vars.up_file.filename
if form.process().accepted:
redirect(URL('data', 'index'))
elif form.errors:
response.flash = "form has errors"
and my db.py excerpt:
db.define_table('uploads',
Field('username', 'string'),
Field('filename', represent = lambda x, row: "None" if x == None else x[:45]),
Field('up_file', 'upload', uploadseparate=True, requires=[IS_NOT_EMPTY(), IS_UPLOAD_FILENAME(extension=ext_regex)]),
Field('up_date', 'datetime'),
Field('up_size', 'integer', represent= lambda x, row: quikr_utils.sizeof_fmt(x) ),
Field('notes', 'text'))
Currently the validation doesn't appear to do anything, when I submit my function, the filename isn't getting saved for some reason, and i get an error elsewhere because the value is None
You need to do something like this :
DB :
db.define_table('t_filetable',
Field('f_filename', type='string', label=T('File Name')),
Field('f_filedescription', type='text',
represent=lambda x, row: MARKMIN(x),
comment='WIKI (markmin)',
label=T('Description')),
Field('f_filebinary', type='upload', notnull=True, uploadseparate=True,
label=T('File Binary')),
auth.signature,
format='%(f_filename)s',
migrate=settings.migrate)
Controller : (default.py)
#auth.requires_login()
def addfile():
form = SQLFORM(db.t_filetable, upload=URL('download'))
if form.process(onvalidation=validate_filename).accepted:
response.flash = 'success'
elif form.errors:
response.flash = 'form has errors'
return dict(form=form)
def validate_filename(form):
if form.vars.f_filename == "":
form.vars.f_filename = request.vars.f_filebinary.filename
Function validate_filename is called AFTER the form has been validated, so form.vars should be available to use here. Function validate_filename checks if form.vars.f_filename has any value other than "" (blank) ; if not, it reads the filename from the request.vars.f_filebinary and assigns it to the form.vars.f_filename . This way you can allow users to provide an optional field for filename. If they leave it blank, and just upload the file, the f_filename in DB will be the original filename.
I tried your pasting your code into web2py to see where it goes wrong and it actually worked for me (at least the file names saved). Maybe the problem is elsewhere?

web2py ajax issue onclick

I am trying to write a controller method and a corresponding view which will call the controller on web2py using Ajax. The idea is to make a small update on the database and return a simple updated message on a target div using Ajax. Below is contoller method:
def deleteajax():
recid1 = request.vars.recid
reptype1 = request.vars.reptype
if recid1 == None:
out = 'Missing Param : recid'
return out
if reptype1 == None:
reptype1 = 'pr'
if reptype1 == 'pr':
row = db2(db2.prs_mailed.id==recid1).select().first()
return str(row.id)
elif reptype1 == 'tb':
row = db2(db2.tbs_mailed.id==recid1).select().first()
else:
return 'Please provide the parameter : rep'
if row['action'] == 'D':
out = 'Already deleted'
return out
else:
row.update_record(action='D')
out = 'Deleted Successfully!'
return out
and this is how I am calling the same from view:
<form>{{
response.write('<input type="hidden" name="recid" value="'+str(response._vars['prs']['id'][k])+'"/>',escape=False)}}
<input type ='button' name="del" value = "D" onclick="ajax('deleteajax', ['reid'], 'target')" />
<div id="target"></div>
</form>
I have tested the controller individually using a POST call and that works. Even the AJAX call works and displays error messages like 'Missing Param : recid' on the target div. I even tried modifying the controller to show more messages after finishing each statement. However, post any database operation, no commands from the controller are getting executed, nor is anything showed on the target div. Where am I going wrong?
First, instead of this:
{{response.write('<input type="hidden" name="recid" value="' +
str(response._vars['prs']['id'][k])+'"/>',escape=False)}}
Just do this:
<input type="hidden" name="recid" value="{{=prs['id'][k])}}"/>
There's no need to use response.write or to access the "prs" object through response._vars (all the items in response._vars are available globally in the view environment).
Regarding the Ajax problem, your input element name is "recid", but your ajax() call refers to "reid". Change the latter to "recid" and see if it works.
UPDATE:
To create multiple unique recid's, you could do:
name="{{='recid%s' % prs['id'][k]}}"
Then, in the controller, check for request.vars that start with "recid":
recid = [v for v in request.post_vars if v.startswith('recid')]
if recid:
recid = int(recid[0][5:])
[code to delete record with id==recid]

Categories