Python / Django - Local variable designed before assignment - python

I know this topic is talked many times in Stackoverflow but it concerns many different methods and I need help. I'm stuck since four hours ^^'
Here is the message : local variable 'menuItem' referenced before assignment
def B2BpartnerMenuDetailModify(request, partnerId, menuId, menuItemId):
message = ''
e = B2BpartnerUser(request, partnerId)
try:
menuDetail = Menu.objects.get(id=menuId)
except Menu.DoesNotExist:
return logoutUser(request)
if request.method == 'POST':
form = MenuDetailForm(request.POST, mySelf=partnerId)
if form.is_valid():
descrShort = form.cleaned_data['descrShort']
paragraph = form.cleaned_data['paragraph']
producteur = form.cleaned_data['producteur']
position = MenuItem.objects.filter(menuId = menuDetail).filter(paragraph = paragraph).count() + 1
menuItem = MenuItem(menuId = menuDetail)
menuItem.descrShort = descrShort
menuItem.paragraph = paragraph
menuItem.producteur = producteur
menuItem.save()
if producteur > 0:
menuItemProd = MenuItemProd(menuItemId = menuItem)
menuItemProd.entrepriseId = producteur
menuItemProd.save()
message = _('Details modified successfuly')
else:
data = {'descrShort': menuItem.descrShort, 'paragraph': menuItem.paragraph, 'producteur': menuItem.producteur}
form = MenuDetailForm(initial=data)
menuItems = MenuItem.objects.filter(menuId = menuDetail).select_related()
menus = Menu.objects.filter(entrepriseId=e)
menuParagraph = MenuParagraph.objects.filter(actif=1)
modifier = True
#detail = False
return render (request, 'front/B2Bmenu.html', {'MenuDetailForm': form, 'menus': menus, 'message': message, 'partnerId': partnerId, 'modifier': modifier, 'detail': detail, 'menuDetail': menuDetail, 'menuParagraph': menuParagraph, 'menuId': menuId, 'menuItems': menuItems})
I'm sure I can get my page when this error is resolved. I'm sure it's a little error, I'm a beginner at Python but I love the language :)
If you want I can give you more details but I don't think it's necessary ^^
Have a nice day and thank you for your help :)

I found it !
I just forgot to add another try for this variable, just after the first try.
try:
menuItem = MenuItem.objects.get(id=menuItemId)
except MenuItem.DoesNotExist:
return logoutUser(request)

Related

Django 2 different error: "local variable referenced before assignment" + "The view didn't return an HttpResponse object. It returned None instead. "

I try to render this view for a Django project and i can get out from these two errors.
The first one is "local variable 'list_of_data' referenced before the assignment. After I change the scope of that variable I get another error "The view didn't return an HttpResponse object. It returned None instead."
I tried a few solutions founded around on the web but i couldn't resolve them.
Here is the views code:
def forecast(request):
if request.method == 'POST':
city = urllib.parse.quote_plus(request.POST['city'])
source = urllib.request.urlopen('http://api.openweathermap.org/data/2.5/weather?q='+ city +'&units=metric&appid=API_KEY').read()
list_of_data = json.loads(source)
day = datetime.datetime.today()
today_date = int(day.strftime('%d'))
forcast_data_list = {} # dictionary to store json data
#looping to get value and put it in the dictionary
for c in range(0, list_of_data['cnt']):
date_var1 = list_of_data['list'][c]['dt_txt']
date_time_obj1 = datetime.datetime.strptime(date_var1, '%Y-%m-%d %H:%M:%S')
if int(date_time_obj1.strftime('%d')) == today_date or int(date_time_obj1.strftime('%d')) == today_date+1:
# print(date_time_obj1.strftime('%d %a'))
if int(date_time_obj1.strftime('%d')) == today_date+1:
today_date += 1
forcast_data_list[today_date] = {}
forcast_data_list[today_date]['day'] = date_time_obj1.strftime('%A')
forcast_data_list[today_date]['date'] = date_time_obj1.strftime('%d %b, %Y')
forcast_data_list[today_date]['time'] = date_time_obj1.strftime('%I:%M %p')
forcast_data_list[today_date]['FeelsLike'] = list_of_data['list'][c]['main']['feels_like']
forcast_data_list[today_date]['temperature'] = list_of_data['list'][c]['main']['temp']
forcast_data_list[today_date]['temperature_max'] = list_of_data['list'][c]['main']['temp_max']
forcast_data_list[today_date]['temperature_min'] = list_of_data['list'][c]['main']['temp_min']
forcast_data_list[today_date]['description'] = list_of_data['list'][c]['weather'][0]['description']
forcast_data_list[today_date]['icon'] = list_of_data['list'][c]['weather'][0]['icon']
today_date += 1
else:
pass
#returning the context with all the data to the forecast.html
context = {
'forcast_data_list':forcast_data_list
}
return render(request, 'forecast.html', context)
If i run this view i get the "local data referenced before assignment" error.
PS: For some reason the first time it works...
Thanks for any help.
If the request.method is not a POST, list_of_data never gets defined because of the if statement. Define list_of_date = [] outside of the if statement.

How do I make it so I only need my api key referenced once?

I am teaching myself how to use python and django to access the google places api to make nearby searches for different types of gyms.
I was only taught how to use python and django with databases you build locally.
I wrote out a full Get request for they four different searches I am doing. I looked up examples but none seem to work for me.
allgyms = requests.get('https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=38.9208,-77.036&radius=2500&type=gym&key=AIzaSyDOwVK7bGap6b5Mpct1cjKMp7swFGi3uGg')
all_text = allgyms.text
alljson = json.loads(all_text)
healthclubs = requests.get('https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=38.9208,-77.036&radius=2500&type=gym&keyword=healthclub&key=AIzaSyDOwVK7bGap6b5Mpct1cjKMp7swFGi3uGg')
health_text = healthclubs.text
healthjson = json.loads(health_text)
crossfit = requests.get('https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=38.9208,-77.036&radius=2500&type=gym&keyword=crossfit&key=AIzaSyDOwVK7bGap6b5Mpct1cjKMp7swFGi3uGg')
cross_text = crossfit.text
crossjson = json.loads(cross_text)
I really would like to be pointed in the right direction on how to have the api key referenced only one time while changing the keywords.
Try this for better readability and better reusability
BASE_URL = 'https://maps.googleapis.com/maps/api/place/nearbysearch/json?'
LOCATION = '38.9208,-77.036'
RADIUS = '2500'
TYPE = 'gym'
API_KEY = 'AIzaSyDOwVK7bGap6b5Mpct1cjKMp7swFGi3uGg'
KEYWORDS = ''
allgyms = requests.get(BASE_URL+'location='+LOCATION+'&radius='+RADIUS+'&type='+TYPE+'&key='+API_KEY) all_text = allgyms.text
alljson = json.loads(all_text)
KEYWORDS = 'healthclub'
healthclubs = requests.get(BASE_URL+'location='+LOCATION+'&radius='+RADIUS+'&type='+TYPE+'&keyword='+KEYWORDS+'&key='+API_KEY)
health_text = healthclubs.text
healthjson = json.loads(health_text)
KEYWORDS = 'crossfit'
crossfit = requests.get(BASE_URL+'location='+LOCATION+'&radius='+RADIUS+'&type='+TYPE+'&keyword='+KEYWORDS+'&key='+API_KEY)
cross_text = crossfit.text
crossjson = json.loads(cross_text)
as V-R suggested in a comment you can go further and define function which makes things more reusable allowing you to use the that function in other places of your application
Function implementation
def makeRequest(location, radius, type, keywords):
BASE_URL = 'https://maps.googleapis.com/maps/api/place/nearbysearch/json?'
API_KEY = 'AIzaSyDOwVK7bGap6b5Mpct1cjKMp7swFGi3uGg'
result = requests.get(BASE_URL+'location='+location+'&radius='+radius+'&type='+type+'&keyword='+keywords+'&key='+API_KEY)
jsonResult = json.loads(result)
return jsonResult
Function invocation
json = makeRequest('38.9208,-77.036', '2500', 'gym', '')
Let me know if there is an issue

Conditioning without if - Django python

I want to choose one thing or the other but I can't use an if statement since an error occurs even if i just try it.
How can i structure the code so that if possible, I do this:
i = Image(entry = e,\
image = request.FILES['file'],))
i.save()
and if it wasn't possible, I should do this instead:
i = Image(entry = e,\
url = request.POST['website'])
i.save()
The basic thing I'm actually checking is if i can call request.FILES, since my image is either just a URL or a local file itself, but I can't try it in an if statement.
Thank you
Simple solution:
kw = {'entry': e}
if 'file' in request.FILES:
kw['image'] = request.FILES['file']
elif 'url' in request.POST:
kw['url'] = request.POST['website']
else:
raise SomeException()
i = Image(**kw)
i.save()
but you'd be better using a Form or ModelForm with custom validation...
try:
i = Image(entry = e,\
image = request.FILES['file'],))
i.save()
except:
i = Image(entry = e,\
url = request.POST['website'])
i.save()

How to make my home page very fast?

It works and I want to make it super fast. The index page is very static, doesn't really change for days unless date updates or a map updates. So it should be possible to optimize to very fast since it doesn't change much. I recently migrated to HRD and my URI is montaoproject.appspot.com I rewrote this so that it is only python and django / html (no data layer trip.) Memcache? Other options? Reduce javascript? I first made sure that data layer isn't touched:
def get(self):
logo = ''
if get_host().find('.br') > 0:
cookie_django_language = 'pt-br'
logo = 'montao'
elif get_host().find('allt') > 0 and not self.request.get('hl'):
logo = ''
cookie_django_language = 'sv'
elif get_host().find('gralumo') > 0 \
and not self.request.get('hl'):
cookie_django_language = 'es_AR' # learn
else:
logo = ''
cookie_django_language = self.request.get('hl', '') # edit
if cookie_django_language:
if cookie_django_language == 'unset':
del self.request.COOKIES['django_language']
else:
self.request.COOKIES['django_language'] = \
cookie_django_language
translation.activate(cookie_django_language)
loginmsg = ''
user = users.get_current_user()
twittername = None
client = OAuthClient('twitter', self)
if client.get_cookie():
info = client.get('/account/verify_credentials')
twittername = info['screen_name']
# seconds_valid = 8600
# self.response.headers['Cache-Control'] = "public, max-age=%d" % seconds_valid
if logo == 'montao':
self.render(
u'montao',
host=get_host(),
twittername=twittername,
continue_url=get_host(),
loginmsg=loginmsg,
form_url=blobstore.create_upload_url('/fileupload'),
user_url=(api.users.create_logout_url(self.request.uri) if api.users.get_current_user() else api.users.create_login_url(self.request.uri)),
admin=users.is_current_user_admin(),
user=(users.get_current_user() if users.get_current_user() else ''
),
logo=logo,
)
else:
self.render(
u'home',
host=get_host(),
twittername=twittername,
continue_url=get_host(),
loginmsg=loginmsg,
form_url=blobstore.create_upload_url('/fileupload'),
latest=Ad.all().filter('published =',
True).order('-modified').get(),
user_url=(api.users.create_logout_url(self.request.uri) if api.users.get_current_user() else api.users.create_login_url(self.request.uri)),
admin=users.is_current_user_admin(),
guser=(users.get_current_user() if users.get_current_user() else ''
),
logo=logo,
)
I don't know python, but if it doesn't change for days I am sure you could write something to convert the above into HTML (say every hour), and then just serve the HTML version. That will give you one of the largest optimisations possible, since your home page then doesn't have to be processed by a script engine at all.
Normally, I'd recommend inverting the page, putting index.html out as a static-file, as well as css and js files, then making an AJAX request to the server to fill in dynamic bits. Static files load really fast.
You might still be able to pull that off, by using client-side JavaScript to figure out which logo and such to use, but getting the file upload form rendered is going to be slower, since the create_upload_url needs to happen server side.

GAE Datastore Put()

def post(self):
update = self.request.get('update')
if users.get_current_user():
if update:
personal = db.GqlQuery("SELECT * FROM Personal WHERE __key__ = :1", db.Key(update))
personal.name = self.request.get('name')
personal.gender = self.request.get('gender')
personal.mobile_num = self.request.get('mobile_num')
personal.birthdate = int(self.request.get('birthdate'))
personal.birthplace = self.request.get('birthplace')
personal.address = self.request.get('address')
personal.geo_pos = self.request.get('geo_pos')
personal.info = self.request.get('info')
photo = images.resize(self.request.get('img'), 0, 80)
personal.photo = db.Blob(photo)
personal.put()
self.redirect('/admin/personal')
else:
personal= Personal()
personal.name = self.request.get('name')
personal.gender = self.request.get('gender')
personal.mobile_num = self.request.get('mobile_num')
personal.birthdate = int(self.request.get('birthdate'))
personal.birthplace = self.request.get('birthplace')
personal.address = self.request.get('address')
personal.geo_pos = self.request.get('geo_pos')
personal.info = self.request.get('info')
photo = images.resize(self.request.get('img'), 0, 80)
personal.photo = db.Blob(photo)
personal.put()
self.redirect('/admin/personal')
else:
self.response.out.write('I\'m sorry, you don\'t have permission to add this LP Personal Data.')
Should this will update the existing record if the 'update' is querystring containing key datastore key. I try this but keep adding new record/entity. Please give me some sugesstion to correctly updating the record/entity.
Correction? :
def post(self):
update = self.request.get('update')
if users.get_current_user():
if update:
personal = Personal.get(db.Key(update))
personal.name = self.request.get('name')
personal.gender = self.request.get('gender')
personal.mobile_num = self.request.get('mobile_num')
personal.birthdate = int(self.request.get('birthdate'))
personal.birthplace = self.request.get('birthplace')
personal.address = self.request.get('address')
personal.geo_pos = self.request.get('geo_pos')
personal.info = self.request.get('info')
photo = images.resize(self.request.get('img'), 0, 80)
personal.photo = db.Blob(photo)
personal.put()
self.redirect('/admin/personal')
else:
personal= Personal()
personal.name = self.request.get('name')
personal.gender = self.request.get('gender')
personal.mobile_num = self.request.get('mobile_num')
personal.birthdate = int(self.request.get('birthdate'))
personal.birthplace = self.request.get('birthplace')
personal.address = self.request.get('address')
personal.geo_pos = self.request.get('geo_pos')
personal.info = self.request.get('info')
photo = images.resize(self.request.get('img'), 0, 80)
personal.photo = db.Blob(photo)
personal.put()
self.redirect('/admin/personal')
else:
self.response.out.write('I\'m sorry, you don\'t have permission to add this LP Personal Data.')
There's no need to do a query when you know the key: Simply call db.get() on the key to retrieve it directly, which is much faster than doing a query.
As to why you're creating a new record each time, it looks like you're not passing in 'update' to your page correctly. Try logging the query string parameters to see what's going wrong.
I finally answer this myself, Thanks for Nick Johnson guide on this.
I cannot get the query string url as 'string key' that always raise BadKeyError: Invalid string key exception.
I try to put this 'update' string as hidden field on html edit form and this works since 'update' is a valid 'string key' now.
def post(self):
update = self.request.get('update')
if users.get_current_user():
if update != '':
personal = Personal.get(db.Key(update))

Categories

Resources