Did not look into your code. But this kind of situation usually is caused by a form receives variables from both GET and POST. In this case, request.vars.myvar=['blah', 'blah'], but request.get_vars.myvar='blah', and request.post_vars.myvar='blah'. So you can choose to use only one of it.
On Jun2, 9:15pm, Andrew Buchan <andyha...@gmail.com> wrote: > Hello, > > I've had this issue before, where a string which is passed as part of > request.vars somehow becomes a list when the form is submitted. The > way I got round it at the time was by doing: > > if isinstance(thread_id, list): > thread_id = thread_id[0] > > However, that just doesn't feel right, and will only work where the > value never changes (i.e. I can assume that all items in the list have > the same value so [0] is as good as any), and more to the point, it > doesn't address why this is happening in the first place. > > I tried the suggestion in post 17355 of this mailing group which seems > to suggest explicitly passing the vars on submit by adding the > following to the submit button: > > _action=URL(r=request,args=request.args) > > However, that doesn't work either. > > I've posted some code below where this is happening to the variable > "thread_id", if you look at the 8th & 9th line of function > addreplacementpage() you'll see that I test whether the variable is a > list or not, and it proves positive only when the form is submitted, > i.e. the function goes round the loop a second time (self-submitting > form). > > Has anyone else experienced this or have a solution to the problem, or > even better: advice on how to figure out what's going on in these kind > of situations? > Also, feel free to bash the code, constructively... > > regards, > > Andy. > ------------- > > def addreplacement(): > #Call this function from other pages, it will initialise the > PartLists and SelectedParts session > #variables if required, generate a thread_id and then redirect to > addreplacementpage function below. > #These two session variables store the partlist and currently- > selected-item-in-partlist(for delete/edit purposes) > #for the replacement currently being worked on (either newly > raised or amended) > #The 'thread_id' var is used to allow multiple replacements to be > edited within the same session, > #so for the replacement currently being edited use > session.PartLists[thread_id] to obtain prt list > #and session.SelectedParts[thread_id] to obtain selected part. > Complaint_Base_id = request.vars.record > title = 'Complaint Raised' > if not (Complaint_Base_id ): > return ComplaintSystem.__ShowSimplePage(globals(), > dict(message = "Record id was not supplied with request." , > title=title)) > thread_id = int(uuid.uuid4()) > if not session.PartLists: > session.PartLists = dict() > session.PartLists[thread_id] = dict() > if not session.SelectedParts: > session.SelectedParts = dict() > session.SelectedParts[thread_id] = -1 > redirect(URL(r=request, f='addreplacementpage', > vars={'record':Complaint_Base_id, 'thread_id':thread_id})) > > def addreplacementpage(): > #This must only ever be called by function 'addreplacement' > title = 'Complaint Raised' > Complaint_Base_id = request.vars.record > thread_id = request.vars.thread_id > assert(Complaint_Base_id ) > assert(thread_id) > if isinstance(thread_id, list): > return 'its a list!!!!!' > response.view = 'Complaints/AddReplacement.html' > response.title = title > Table = db.Replacement > form = GenerateReplacementForm( thread_id = thread_id ) > if form.accepts(request.vars, session): > FieldValues = dict() > for f in Table.fields: > if form.vars.has_key(f): > FieldValues[f] = form.vars[f] > FieldValues['Complaint_Base_id'] = Complaint_Base_id > ReplacementId = Table.insert(**FieldValues) > for key, value in session.PartLists[thread_id].items(): > db.Replacement_Part.insert(Replacement_id=ReplacementId, > Row_Index=key, Part_Number=value[0], Description=value[1], > Cost=value[2], Quantity=value[3]) > return ComplaintSystem.__ShowSimplePage(globals(), > dict(message='New record created', title='Record Created', links = > links)) > return dict(form = form, id = Complaint_Base_id ) > > def GenerateReplacementForm( thread_id , Rec_ID = None): > Table = db.Replacement > Fields = list(db.Replacement.fields) > for i in ['Complaint_Base_id', 'Status', 'Date_Authorised', > 'Project_Coordinator']: > Fields.remove(i) > if Rec_ID : > form = SQLFORM(Table, record = Rec_ID , showid=False, fields = > Fields) > else: > form = SQLFORM(Table, fields = Fields) > > form.custom.submit = INPUT(_type="submit", _value="Submit", > _action=URL(r=request,args=request.args)) > > ajaxAddPart = "ajax('%s', %s, 'partfielderrors');ajax('%s', > %s,'target');" % \ > (URL(r=request,f='validatepart'), PartFieldsString, > URL(r=request, f='addpart'), PartFieldsString) > innertable = TABLE( > TR( > TD( > TABLE( > TR(TD(B('Add Part:')), TD(INPUT(_type='hidden', > _id='thread_id', _name='thread_id', _value=thread_id)), TD()), > TR( > TD(LABEL('Part No')), > TD(LABEL('Description')), TD(LABEL('Cost')), TD(LABEL('Quantity'))), > TR( > TD(INPUT(_type="text", _id='partno', > _name='partno', _class='partnofield' )), > TD(INPUT(_type='text', _id='description', > _name='description', _class='descriptionfield' )), > TD(INPUT(_type='text', _id='cost', > _name='cost', _class='numericfield')), > TD(INPUT(_type='text', _id='quantity', > _name='quantity', _class='numericfield'))) > ) > ) > ), > TR( > TD( > TABLE( > TR( > TD(INPUT(_type='button', _value='Add part', > _onclick=ajaxAddPart)), > TD(DIV('', _id='partfielderrors', > _class='error' )) > ) > ) > ) > ), > _class='tablewithborder' > ) > outtertable = TABLE( > TR(TD(B('Replacement Parts:'))), > TR(TD(DIV(__refreshtable(thread_id), _id='target'))), > TR(TD(innertable )), > _class='tablewithborder') > > form[0][12].insert(1, TR(TD(), TD(outtertable))) > return form > > def __refreshtable(thread_id): > if isinstance(thread_id,list): > thread_id = thread_id[0] > if session.PartLists and session.PartLists.has_key(thread_id): > partlist = session.PartLists[thread_id] > else: > partlist = dict() > > if len(partlist.items()) > 0: > table = TABLE(TR(TD(INPUT(_type='hidden', _id='thread_id', > _value=thread_id)), TD(LABEL('Part No')), TD(LABEL('Description')), > TD(LABEL('Cost')), TD(LABEL('Quantity'))), > _class='tablewithinnerborder') > rowcnt = 0 > sel_func = URL(r=request,f='selectpart') > ajaxRemovePart = "ajax('%s', ['thread_id'], 'target');" % > URL(r=request, f='removepart') > ajaxeditpart = "ajax('%s',['thread_id'],'target');" % > URL(r=request,f='editpart') > Total = 0.0 > IndicesList = list(partlist .iterkeys())# use this so we have > parts listed in order they were added... > IndicesList.sort() > for key in IndicesList: > value = partlist[key] > rowcnt += 1 > idstr = 'partselection%s' % key > fieldsString = "['%s', 'thread_id']" % idstr > cost = value[2] > quantity = value[3] > table.insert(rowcnt , TR( > TD(INPUT(_type='radio', _name='partselect', _id = > idstr , _value = key, _onclick="ajax('%s', %s);" %(sel_func , > fieldsString))), > TD(INPUT(_type='text', _disabled=True, > _value=value[0], _class='partnofield' )), > TD(INPUT(_type='text', _disabled=True, > _value=value[1], _class='descriptionfield' )), > TD(INPUT(_type='text', _disabled=True, _value=cost , > _class='numericfield')), > TD(INPUT(_type='text', _disabled=True, > _value=quantity , _class='numericfield')) > )) > Total += quantity * cost > table.insert(rowcnt + 1, TR( > TD(), > TD(), > TD(LABEL('Total Replacement Cost:')), > TD(INPUT(_type='text', _disabled=True, _value=Total, > _class='numericfield')), > TD()) > ) > table.insert(rowcnt + 2, TR( > TD(), > TD(INPUT(_type='button', _value='Remove Selected', > _onclick=ajaxRemovePart )), > TD(INPUT(_type='button', _value='Edit Selected', > _onclick=ajaxeditpart )), > TD(INPUT(_type='hidden', _id='dummy')), > TD()) > ) > return table > else: > return '(No replacement parts)'