Browser shows variable refered before assign - django

here is the image of error that i am getting in the browser
I am new to python and hardly tried to figure out the problem of usese of variable from another if statement in the same function
here is my code:
def post(self, request, **kwargs):
selected_membership_type = request.POST.get('membership_type')
user_membership = get_user_membership(request)
user_subscription = get_user_subscription(request)
selected_membership_qs = Membership.objects.filter(
membership_type=selected_membership_type)
if selected_membership_qs.exists():
selected_membership = selected_membership_qs.first()
'''
==========
VALIDATION
==========
'''
# selected_membership = selected_membership_qs.first()
if user_membership.membership == selected_membership:
if user_subscription == None:
messages.info(request,"You already have this membership.Your \
next payment is due {}".format('get this value from stripe'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))

The problem is the following:
if selected_membership_qs.exists():
selected_membership = selected_membership_qs.first()
You are only assigning selected_membership if the if is True.
So in your case you are getting the Variable referenced before assignment error because the if is False.
Therefore selected_membership is never assigned.
If you do something like this
selected_membership = None
if selected_membership_qs.exists():
selected_membership = selected_membership_qs.first()
it should work.

Related

Django: Not fetching the same object

I have a form where i am entering four details 'Persona Name', 'Persona Key' ,'Persona Key Label' and 'Persona Key Value' and on entering these values i am pressing Submit button which generates a GET request on my server.
Following are django views:-
def PersonaSave(request):
persona_name = request.GET.get('persona_name',)
persona_key = request.GET.get('key_name',)
persona_key_value = request.GET.get('key_value',)
persona_key_label = request.GET.get('key_label',)
persona_submit = request.GET.get('Save',)
return( persona_name , persona_key , persona_key_label , persona_key_value , persona_submit )
def TestPageView(request):
x=PersonaSave(request)
persona_name = x[0]
persona_key = x[1]
persona_key_label=x[2]
persona_key_value=x[3]
persona_submit=x[4]
if(persona_name is None and persona_key is None and persona_key_label is None and persona_key_value is None):
return render(request, 'dashboard/test_page.html')
elif TestPersonaName.objects.filter(name=persona_name).exists():
t= TestPersonaName.objects.get(pk=persona_name)
testpersona = TestPersona.objects.get(name=t)
if testpersona.key == persona_key:
testpersona.label= persona_key_label
testpersona.value = persona_key_value
t=TestPersonaName(name=persona_name)
t.save()
testpersona = TestPersona(name=t,key=persona_key,label=persona_key_label,value=persona_key_value)
testpersona.save()
return render(request,'dashboard/test_page.html')
I am rewriting codes of lines where updation and new persona formation starts to maintain the clarity of question.
Update Function starts from here-----
elif TestPersonaName.objects.filter(name=persona_name).exists():
t= TestPersonaName.objects.get(pk=persona_name)
testpersona = TestPersona.objects.get(name=t)
if testpersona.key == persona_key:
testpersona.label= persona_key_label
testpersona.value = persona_key_value
-----This is where update function ends
If persona name is different then complete new TestPersonaName object and TestPersona object will be formed.
For this the function starts here----
t=TestPersonaName(name=persona_name)
t.save()
testpersona = TestPersona(name=t,key=persona_key,label=persona_key_label,value=persona_key_value)
testpersona.save()
----and ends here.
Now the problem is for the same persona name and same persona key two different TestPersona objects are being formed. For e.g If I enter persona_name = Ankit,
key = 'city' and value = 'New Delhi' and later i want to change city so i enter
name='Ankit' , key = 'city' and name = 'Lucknow'. On pressing submit two different TestPersona objects are being formed. i.e
object1(name='Ankit',key='city', value='New Delhi') and
object2(name='Ankit',key='city',value='Lucknow')
Ideally it should be:-
object1(name='Ankit', key='city', value='Lucknow')
Following are TestPersonaName and TestPersona models:-
class TestPersonaName(models.Model):
name = models.CharField(max_length=100,primary_key=True)
class TestPersona(models.Model):
name = models.ForeignKey('TestPersonaName',on_delete=models.CASCADE)
key = models.CharField(max_length=200)
label = models.CharField(max_length=200,null=True,blank=True)
value = models.CharField(max_length=200)
elif TestPersonaName.objects.filter(name=persona_name).exists():
t= TestPersonaName.objects.get(pk=persona_name)
testpersona = TestPersona.objects.get(name=t)
if testpersona.key == persona_key:
testpersona.label= persona_key_label
testpersona.value = persona_key_value
You need too save the persona and return here as in the if above. Otherwise the interpreter exits this block and continues with
t=TestPersonaName(name=persona_name)
t.save()
testpersona = TestPersona(name=t,key=persona_key,label=persona_key_label,value=persona_key_value)
testpersona.save()
which replaces the value of t with a new persona that gets saved to DB. After every attempt to edit you'll keep ending up with a new record.

Replacement for django `render_options`

So I am implementing this answer: Country/State/City dropdown menus inside the Django admin inline, but the def render piece of code needs to be redone.... I have managed to redo it, but I am struggling to find a replacement (or the correct code) for the self.render_options method (which was deprecated on 1.11) of the Widget class.
I am on Django 2.1.
What should I change?
Here is my code:
class StateChoiceWidget(widgets.Select):
def render(self, name, value, attrs=None, renderer=None):
self.choices = [(u"", u"---------")]
if value is None:
value = ''
model_obj = self.form_instance.instance
if model_obj and model_obj.country:
for m in model_obj.country.state_set.all():
self.choices.append((m.id, smart_text(m)))
else:
obj = State.objects.get(id=value)
for m in State.objects.filter(country=obj.country):
self.choices.append((m.id, smart_text(m)))
final_attrs = self.build_attrs(attrs)
output = ['<select%s>' % flatatt(final_attrs)]
for option in self.choices:
output.append('<option value="%s">%s</option>' % (option[0], option[1]))
output.append('</select>')
return mark_safe(''.join(output))
Original poster updated the sample code, so now it doesn't show the code in the question: see previous revision https://stackoverflow.com/revisions/52174508/1
So I figured out the answer. Will post it here in case someone runs into the same issue.
class StateChoiceWidget(widgets.Select):
def render(self, name, value, attrs=None, renderer=None):
self.choices = [(u"", u"---------")]
if value is None or value == '':
value = ''
model_obj = self.form_instance.instance
if model_obj and model_obj.country:
for m in model_obj.country.state_set.all():
self.choices.append((m.id, smart_text(m)))
else:
obj = State.objects.get(id=value)
for m in State.objects.filter(country=obj.country):
self.choices.append((m.id, smart_text(m)))
final_attrs = self.build_attrs(attrs)
s = widgets.Select(choices=self.choices)
select_html = s.render(name=name,value=value,attrs=attrs)
return mark_safe(''.join(select_html))

local variable 'instance' referenced before assignment error

Now I've read all the posts on SO regarding this error, and I can conclude that my error is quite a different case.
The error:
Local variable 'instance' referenced before assignment
[21/Jun/2018 09:05:58] "POST /details/create/ HTTP/1.1" 400 54
Now here's the code where I initialize instance:
def create(request):
if request.method == "POST":
try:
params = post_data(request)
try:
instance = Sales_detail.objects.get(id = params.get("id",None))
params["item"] = instance.item.pk
params["price"] = instance.price.pk
params["sales"] = instance.sales.pk
detail_form = Detail_form(params, instance = instance)
except Sales_detail.DoesNotExist:
params["item"] = instance.item.pk
params["price"] = instance.price.pk
params["sales"] = instance.sales.pk
detail_form = Detail_form(params)
if detail_form.is_valid():
detail_form.save()
else:
raise_error(detail_form.errors,True)
return success("Details successfully saved.")
except Exception as e:
return error(e)
else:
return redirect("dashboard")
I have no idea what I'm missing, clearly instance is initialized before doing anything with it.
An error occurs when this line
instance = Sales_detail.objects.get(id = params.get("id",None))
is executed. The code isn't enecuted completely. So the instance hasn't been definited. And then the code goes to
params["item"] = instance.item.pk
Since the instance hasn't been definited, the Error
The error: Local variable 'instance' referenced before assignment
occurs.

How to execute a function when a variable's value is changed?

In Odoo 10, I want to change the value of a variable when the forecasted quantity of a product is changed. I tried using the #api.onchange decorator, but it doesn't work. The forecasted quantity change, but the variable keeps the same value. I have this:
class MyProduct(models.Model):
_inherit = 'product.product'
was_changed = fields.Boolean(default = False)
#api.onchange('virtual_available')
def qtychanged(self):
self.was_changed = True
_logger.info('Product_Qty_Cahnged: %s',str(self.virtual_available))
In this code, if the forecasted quantity of a product would change, the variable was_changed should be set to True, but nothing happens.
After that, I tried to overwrite the write method for my custom class, like this:
class MyProduct(models.Model):
_inherit = 'product.product'
was_changed = fields.Boolean(default=False)
#api.multi
def write(self, values):
if values['virtual_available']:
values['was_changed'] = True
# THE FOLLOWING LINES WERE IN THE ORIGINAL WRITE METHOD
res = super(MyProduct, self).write(values)
if 'standard_price' in values:
self._set_standard_price(values['standard_price'])
return res
But still, I have the same result. I can't seem to get that flag to change. So, any ideas?
Try this:
class MyProduct(models.Model):
_inherit = 'product.product'
was_changed = fields.Boolean(default = False)
#api.onchange('virtual_available')
def qtychanged(self):
self.write({'was_changed': True})
_logger.info('Product_Qty_Cahnged: %s',str(self.virtual_available))

Django No local variable error

I have a problem with one of my functions . I receive this error when I submit a post form without any value.
local variable 'picture' referenced before assignment
Traceback:
File "C:\Python26\Lib\site-packages\django\core\handlers\base.py" in get_response
111. response = callback(request, *callback_args, **callback_kwargs)
File "C:\o\17\mysite\pet\views.py" in BoardEditor
260. return render(request,'boardeditor.html', {'picture':picture,'board':BoardNameForm(request.user),'boardpicture':BoardPictureForm(request.user),})
I think I understand what causing the problem because in my views. I have a picture variable that retrieves all my pictures and if their no value coming from POST . I get this error .
I'm been searching and trying for solutions on how to handle if variable is None and I haven't been successful.
Here are the solutions I tried from all the resources i gathered
If board is None , assign it an empty value.
if forms.is_valid():
board = forms.cleaned_data['board']
if board == None:
picture = ""
How can I combat the error when their is no value toward my picture variable?
You will get this error when your form doesn't validate ( is_valid() return false), so in this case you don't have picture defined at all.
You can just create a context dictionary at begin and then put there variables you want. Something like this
context_data = {}
if form.is_valid():
context_data['picture']=Picture.objects.filter(board=boards)
return render(request,'boardeditor.html',context_data)
[..........]
if forms.is_valid():
board = forms.cleaned_data['board']
picture = "" //<--add
if board:
boards = forms.cleaned_data['board']
picture = Picture.objects.filter(board=boards)
return render(request,'boardeditor.html',{ // align with if board:
'picture':picture,
'board':BoardNameForm(request.user),
'boardpicture':BoardPictureForm(request.user),
})
if formss.is_valid():
pooh = forms.cleaned_data['board']
pict = "" //<--add
if pooh:
pooh = formss.cleaned_data['board']
pict = Picture.objects.filter(board=pooh)
return render(request,'boardeditor.html',{ // align with if pooh:
'pict':pict,
'board':BoardNameForm(request.user),
'boardpicture':BoardPictureForm(request.user),
})
[..........]
Following is the line that causes the error:
return render(request,'boardeditor.html',{'picture':picture,'board':BoardNameForm(request.user),'boardpicture':BoardPictureForm(request.user),})
Reason being that the return statement is not under the if condition so it tries returning the picture variable under all circumstances. So according to your code:
if forms.is_valid():
board = forms.cleaned_data['board']
if board == None:
picture = ""
if board:
boards = forms.cleaned_data['board']
picture = Picture.objects.filter(board=boards)
return render(request,'boardeditor.html',{'picture':picture,'board':BoardNameForm(request.user),'boardpicture':BoardPictureForm(request.user),})
if the if forms.is_valid() condition fails, you are still trying to return picture variable which is undefined. You need to make sure you define the variable before accessing it.
There are a plenty of ways you can do this. For Example:
Example 1:
if forms.is_valid():
board = forms.cleaned_data['board']
if board:
boards = forms.cleaned_data['board']
picture = Picture.objects.filter(board=boards)
else:
picture = '' # or None or False or Whatever
return render(request,'boardeditor.html',{'picture':picture,'board':BoardNameForm(request.user),'boardpicture':BoardPictureForm(request.user),})
Example 2:
picture = '' # or None or False or Whatever
if forms.is_valid():
board = forms.cleaned_data['board']
if board:
boards = forms.cleaned_data['board']
picture = Picture.objects.filter(board=boards)
return render(request,'boardeditor.html',{'picture':picture,'board':BoardNameForm(request.user),'boardpicture':BoardPictureForm(request.user),})
Example 3:
if forms.is_valid():
board = forms.cleaned_data['board']
if board:
boards = forms.cleaned_data['board']
picture = Picture.objects.filter(board=boards)
return render(request,'boardeditor.html',{'picture':picture,'board':BoardNameForm(request.user),'boardpicture':BoardPictureForm(request.user),})
else:
return render(request,'boardeditor.html',{'picture':'','board':BoardNameForm(request.user),'boardpicture':BoardPictureForm(request.user),})
or put all the variables in a dictionary as Aldarund suggested and them pass the dictionary to the context.