i try to update the custom form, for user new entry and user update the same form is used. in submit code i use if else for update and submit, it show an error " string indices must be integers, not str "
views.py:-
def applicationvalue(request):
if request.method == 'POST':
if request.method['usubmit'] == 'new':
getappid = request.POST['appid']
getjobtitle = request.POST['jobtitle']
getodesk = request.POST['odeskid']
getspecification = request.POST['clientspecification']
getnotes = request.POST['notes']
request.session['getappid'] = getappid
getintable = applicationform(user_id = request.user.id , app_id = getappid, job_title = getjobtitle, odesk_id = getodesk, client_specification = getspecification, job_type = request.POST['jobtype'], notes = getnotes)
getintable.save()
return HttpResponseRedirect('/tableview/')
else:
request.method['usubmit'] == 'Update'
saveapplid = request.POST['appid']
savejobtitle = request.POST['jobtitle']
saveodesk = request.POST['odeskid']
savespecification = request.POST['clientspecification']
savenotes = request.POST['notes']
saveapp = applicationform.objects.get(app_id = saveapplid)
saveapp.job_title = savejobtitle
saveapp.odesk_id = saveodesk
saveapp.user_specification = savespecification
saveapp.notes = savenotes
saveapp.save()
return HttpResponse(1)
# return HttpResponseRedirect('/tableview/')
else:
return render_to_response('registration/applicationform.html')
when this code run than it display an error
" string indices must be integers, not str "
request.method is a string (you just tested if it is equal to "POST" in the first if statement)!
Did you meant to test against request.POST['usubmit'] instead?
The line:
if request.method['usubmit'] == 'new':
will throw an error, but perhaps you wanted:
if request.POST['usubmit'] == 'new':
instead. Moreover, the lines:
else:
request.method['usubmit'] == 'Update'
don't do what you think they do. You probably wanted to test if usubmit is equal to 'Update' for the second block:
elif request.POST['usubmit'] == 'Update':
Related
I am trying to pass this eligable list to my template so that I can display it in my website but when I run the website it says that local variable 'eligable' referenced before assignment. I dont understand because this is the only time I used the word eligable in my code.
code:
def specificDate(response):
empName = employeeName.objects.all
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)
eligable = []
for item in overT:
eligable.append(item.date)
print('Hello')
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})
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)
eligable = []
for item in overT:
eligable.append(item.date)
print('Hello')
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})
The error was correct to be there, because in cases where your control would not inside the if block, eligable list won't get intialized , so after encountering the last statement, it would raise the error.
The fix was to pre-initialize the list beforehand.
I am trying to structure a WHERE question LIKE 'Who%' OR question LIKE 'What%' SQL query from inputs of a POST request.
What is the correct way to do this?
If showall POST value is True then no next filter needs to be matched. All entries returned.
If showall is False then combine the next filters for the OR statement to return entries matching only of the filters provided.
https://docs.djangoproject.com/en/3.1/topics/db/queries/#complex-lookups-with-q-objects
from django.db.models import Q
def getuserlist(request):
if request.method == "POST":
showall = request.POST['showall']
showfl_1 = request.POST['showfl_1']
showfl_2 = request.POST['showfl_2']
if showall == 'true':
filt = Q(listing=any)
elif showfl_1 == 'true':
filt = Q(listing="Filtered1")
elif showfl_2 == 'true':
filt = filt | Q(listing="Filtered2")
searchresult = list(User_data.objects.filter(listing=filt).values_list("Country","gender","listing").order_by('-added_date'))
return searchresult
You can construct a Q object that is a disjunction of the options:
from django.http import JsonResponse
if showall != 'true':
filters = []
if showfl_1 == 'true':
filters.append(('listing', 'filtered1'))
if showfl_1 == 'true':
filters.append(('listing', 'filtered2'))
if not filters:
searchresult = User_data.objects.none()
else:
searchresult = Q(*filters, _connector=Q.OR)
else:
searchresult = User_data.objects.all()
searchresult = list(searchresult.values_list(
'Country','gender','listing'
).order_by('-added_date'))
return JsonResponse({'data': searchresult})
You may try something like this
from django.db.models import Q
def getuserlist(request):
if request.method == "POST":
showall = request.POST['showall']
showfl_1 = request.POST['showfl_1']
showfl_2 = request.POST['showfl_2']
c = {}
if showall:
c['listing']= Q(listing=any)
elif showfl_1:
c['listing']= Q(listing="Filtered1")
elif showfl_2:
c['listing'] = Q(listing="Filtered2")
searchresult = list(User_data.objects.filter(**c).values_list("Country","gender","listing").order_by('-added_date'))
return searchresult
I loop through multiple question stored in my DB each question has 5 answers(openness,conscientiousness,extraversion,agreeableness,neuroticism) and am trying to count how many times each answers is repeated and store the scores
Models :
class Reponses(models.Model):
ScoreOp = models.IntegerField(blank=True,null=True)
ScoreCon = models.IntegerField(blank=True,null=True)
ScoreExt = models.IntegerField(blank=True,null=True)
ScoreAgr = models.IntegerField(blank=True,null=True)
ScoreNeu = models.IntegerField(blank=True,null=True)
Product = models.OneToOneField("Product", on_delete=models.CASCADE,null=True)
class Personalite(models.Model):
Question = models.CharField(max_length=50,blank=True)
openness = models.CharField(max_length=20,blank=True)
conscientiousness = models.CharField(max_length=20,blank=True)
extraversion = models.CharField(max_length=20,blank=True)
agreeableness = models.CharField(max_length=20,blank=True)
neuroticism = models.CharField(max_length=20,blank=True)
models.ForeignKey("Reponses", on_delete=models.CASCADE,null=True)
Views :
def home_views(request):
questions= Personalite.objects.all()
product = Product.objects.get(id=5)
if request.method == 'POST':
try:
reponse = Reponses.objects.create()
reponse = Reponses(Product= product)
allRep = []
allRep = request.POST.getlist('poll')
for Rep in allRep:
print(Rep)
if Rep == 'openness':
reponse.ScoreOp = reponse.ScoreOp + 1
elif Rep == 'conscientiousness':
reponse.ScoreCon += 1
elif Rep == 'extraversion':
reponse.ScoreExt += 1
elif Rep == 'agreeableness':
reponse.ScoreAgr += 1
elif Rep == 'neuroticism':
reponse.ScoreNeu += 1
else :
print('HAHAHAHHAHAAH')
reponse.save()
except NameError:
print("An exception occurred",NameError)
context={
'questions':questions
}
return render(request , "home.html",context)
reponse = Reponses(Product= product) this doesn't saves the response object you need to call the save() method so reponse.ScoreOp is None.
Try this.
First create the response object properly.
reponse = Reponses.objects.create(Product=product)
And also instead of specifying the null=True to the integer field provide the default value 0.
ScoreOp = models.IntegerField(default=0) # properly migrate after change in model
Now in the views.
if Rep == 'openness':
reponse.ScoreOp += 1
snippet is as below:
#api.route('/<graphType>/<fieldType>')
def display1(graphType,fieldType):
dbconnection = dbconnector.configuration('farmautomation')
if graphType == "line" and fieldType == "weather details":
dataframe_name = DataFrame_Conversion.weather_details_dataFrame(dbconnection)
groupbyvalue = 'village'
fieldstoaggregate = 'humidity'
datamin, datamax = Groupby.groupby(dataframe_name, groupbyvalue, fieldstoaggregate,
field='humidity')
return Graphs.weather(datamin, datamax)
elif graphType == "pie" and fieldType == "total farmers":
dataframe_name = DataFrame_Conversion.logins_time_dataFrame(dbconnection)
groupbyvalue = 'created_time'
fieldstoaggregate = 'count'
result = Groupby.groupby(dataframe_name, groupbyvalue, fieldstoaggregate,
field='logins')
return Graphs.pie(result)
elif graphType == "bar" and fieldType == "logins":
dataframe_name = DataFrame_Conversion.logins_time_dataFrame(dbconnection)
groupbyvalue = 'created_time'
fieldstoaggregate = 'count'
result = Groupby.groupby(dataframe_name, groupbyvalue, fieldstoaggregate,
field='logins')
return Graphs.bar(result)
The code inside both the condition's(elif's) are same but have different return type, is there a possibility to reduce my code?
I have got no idea to try someway, any help is appreciated
Looks like the 2nd and 3rd conditions are essentially the same, so they could be combined as such:
#api.route('/<graphType>/<fieldType>')
def display1(graphType,fieldType):
dbconnection = dbconnector.configuration('farmautomation')
if graphType == "line" and fieldType == "weather details":
dataframe_name = DataFrame_Conversion.weather_details_dataFrame(dbconnection)
groupbyvalue = 'village'
fieldstoaggregate = 'humidity'
datamin, datamax = Groupby.groupby(dataframe_name, groupbyvalue, fieldstoaggregate,
field='humidity')
return Graphs.weather(datamin, datamax)
elif graphType in ['pie','bar'] and fieldType in ['logins','total farmers']:
dataframe_name = DataFrame_Conversion.logins_time_dataFrame(dbconnection)
groupbyvalue = 'created_time'
fieldstoaggregate = 'count'
result = Groupby.groupby(dataframe_name, groupbyvalue, fieldstoaggregate,
field='logins')
if graphType == 'pie':
return Graphs.pie(result)
else:
return Graphs.bar(result)
There might be a better way yet to refactor, but it depends on if you have more (lots of) cases to test or just these few.
EDIT1: Fixed total farmers string
EDIT2: Based on additional comment/question about lots of paths, added another structure that might work.
Disclaimer: I'm relatively new to Python and this code has not been tested, but the general idea is to consolidate the unbounded parts of your problem to a single spot - in this case a Dictionary - so that you have a single source of truth for that part.
#api.route('/<graphType>/<fieldType>')
def display1(graphType,fieldType):
# Open your db connection
dbconnection = dbconnector.configuration('farmautomation')
# Get your chart data based on selection
chart_args = get_aggregate_data(fieldType, dbconnection)
# Try to get a chart with that data
chart = get_chart(graphType, chart_args)
if chart != None:
return chart
else:
# Throw an error, return None - your callable
pass
class AggregationSettings:
def __init__(self, df_name='', group_by='',
fields_to_agg='', over_field=''):
self.df_name = df_name
self.group_by = group_by
self.fields_to_agg = fields_to_agg
self.over_field = over_field
# This dictionary is what will grow as you add routes
DATAFRAME_TRANSLATE = {
"weather details":AggregationSettings("weather_details","village","humidity","humidity"),
"logins":AggregationSettings("logins_time","created_time","count","logins"),
"total farmers":AggregationSettings("logins_time","created_time","count","logins")
}
def get_aggregate_data(fieldType, db_connection):
agg_setting = DATAFRAME_TRANSLATE.get(fieldType, None)
if agg_setting == None:
# not in the dict
raise ValueError('The specified fieldType is not valid')
df_val = agg_setting.df_name + '_dataFrame'
# NOTE: I'm not familiar with pandas (which I think this is), but I
# suspect there is a way for you to get your return value passing the
# name, not the class explicitly. If not, there are ways around that too
dataframe_name = DataFrame_Conversion.get_by_name(df_val, db_connection)
return Groupby.groupby(dataframe_name, agg_setting.group_by,
agg_setting.fields_to_agg, agg_setting.over_field)
def get_chart(graphType, chart_args):
# I expect the number of charts is small(ish) and bounded,
# so just use if/else hex
if graphType == 'pie':
return Graphs.pie(chart_args)
elif graphType == 'bar':
return Graphs.bar(chart_args)
else:
# handle other cases as needed...
pass
raise ValueError('The specified graphType is not valid')
My view.py looks as follows. I think the error is in this section. I will post a detailed function if this is not sufficient for now. Basically the model that takes total as argument is of type integer.
Edit 1: Writing the entire function so that it can be more helpful.
def subjManip(request):
c= {}
c.update(csrf(request))
subj = None
c.update(csrf(request))
if request.method == 'POST':
form = SubjForm(request.POST)
if form.is_valid():
user = request.user
subj1 = form.cleaned_data['subj1']
subj2 = form.cleaned_data['subj2']
subj3 = form.cleaned_data['subj3']
if subj1 == None and subj2 == None:
raise forms.ValidationError("Both subjs cannot be empty")
tot = float (((float(0.2017 * subj1 )+ float (0.09036 * subj2) + float(0.6309 * subj3) - 5.0269)/ 4.184)
total =int(tot)
elif subj1 == None:
total = subj1
Try replacing tot = (subj1+subj2)/2.2 with tot = (float(subj1) + float(subj2)) / 2.2