How to fix UnboundLocalError in Django website - python

I am getting this error, "local variable 'stu_details' referenced before assignment". How can i fix it please.
views.py
def assignment_page(request):
if request.method == "POST":
get_course_name = request.POST.get('get_course_name')
add_courses_get = add_courses.objects.get(Course_Name=get_course_name)
stu_course_all_stu = add_courses.objects.filter(Course_Name=add_courses_get)
for all_stu_details in stu_course_all_stu:
for stu_details in all_stu_details.student.all():
id_ = stu_details.student_ID
name = stu_details.student_name
context3 = {"stu_details":stu_details, "id_":id_, "name": name, 'stu_course_all_stu':stu_course_all_stu}
return render(request, 'assignment_page.html', context3)
else:
return redirect('/')

It's look like your variable context3 should be array with information about every students. You declare context3 after loop, but stu_details and other variables exist in the loop.
I understand that you need something like this.
context3 = []
for all_stu_details in stu_course_all_stu:
for stu_details in all_stu_details.student.all():
id_ = stu_details.student_ID
name = stu_details.student_name
context3.append({"stu_details":stu_details, "id_":id_, "name": name, 'stu_course_all_stu':stu_course_all_stu})
context = {'context3': context3}
return render(request, 'assignment_page.html', context)
I hope I understand your problem right.

Related

Django object.filter(X__contains = 210922143300) gives error

Please help me out
def search_venues(request):
if request.method == "POST":
searched = request.POST['searched']
titles = Information.objects.get(id=210922143300)
print(titles)
titles = Information.objects.filter(id__contains=21092214330)
print (titles)
return render(request,
'search_titles.html',
{'searched': searched, 'titles': titles})
else:
return render(request, 'search_titles.html', {})
the first print statement gives me: <QuerySet [<Information: Wind energy can deliver vital slash to global warming>]>, like i expect
the second print statement gives me: enter image description here
What should i do, ofc in the future i want to pass my searched variable

local variable 'username' referenced before assignment django

I have created a function called a panel.
When i run the server it gives an error " UnboundLocalError at /service-panel/ local variable 'username' referenced before assignment" .
I don't know what is getting wrong.
Here is views.py
#login_required
def panel(request):
if(request.session.has_key('username')):
username = request.session['username']
data = Enquiry.objects.filter(service=request.session['service'])
return render(request, 'service-provider-panel/base.html', {'username':username, 'data':data})
You have a logical error:
#login_required
def panel(request):
if(request.session.has_key('username')):
username = request.session['username']
data = Enquiry.objects.filter(service=request.session['service'])
else:
# else statement is needed because the variables username and data must be defined.
username = None
data = None
return render(request, 'service-provider-panel/base.html', {'username':username, 'data':data})
The problem is that the condition request.session.has_key('username') can be False. Then, the username variable will not be assigned. The same with data variable.
A solution could be:
#login_required
def panel(request):
username = None
data = None
if(request.session.has_key('username')):
username = request.session['username']
data = Enquiry.objects.filter(service=request.session['service'])
return render(request, 'service-provider-panel/base.html', {'username':username, 'data':data})
You will need to control the logic in the template (service-provider-panel/base.html) when data or username is None.

Django form field update

I have a Django form that lets users choose a tag from multiple tag options. The problem I am facing is that even when the tag list gets updated, the model form does not get the updated tag list from database. As a result, new tags do not appear in options.
Here is my code in forms.py:
class EnglishTagForm(forms.Form):
tag_choices = [(x.tagName, x.tagName.upper()) for x in ClassTag.objects.filter(
agentId=Agent.objects.get(name='English Chowdhury'))]
tag = forms.CharField(widget=forms.Select(choices=tag_choices,
attrs={'class':'form-control'}))
def __init__(self, *args, **kwargs):
super(EnglishTagForm, self).__init__(*args, **kwargs)
self.fields['tag'].choices = [(x.tagName,
x.tagName.upper()) for x in ClassTag.objects.filter(
agentId=Agent.objects.get(name='English Chowdhury'))]
This form is being instantiated in view. My question is what changes should I do so that tag_choices gets updated from database on every instantiation.
How the above form is used in views.py:
```
def complaintDetail(request, complaint_id):
complaint = Complaints.objects.filter(pk=complaint_id).first()
context = {}
if request.method == 'POST':
agent = Agent.objects.get(name="English Chowdhury")
if "SubmitTag" in request.POST:
englishForm = EnglishTagForm(request.POST)
if englishForm.is_valid:
// Complaint Delete Logic
return redirect('chatbot:modComplaints')
else:
englishForm = EnglishTagForm()
context['eForm'] = englishForm
elif "SubmitBundle" in request.POST:
newTagForm = NewTagForm(request.POST)
if newTagForm.is_valid():
// Complaint Delete Logic
complaint.delete()
return redirect('chatbot:modComplaints')
else:
newTagForm = NewTagForm()
context['newForm'] = newTagForm
else:
englishForm = EnglishTagForm()
context['eForm'] = englishForm
newTagForm = NewTagForm()
context['newForm'] = newTagForm
context['complaint'] = complaint
return render(request, 'chatbot/complaintDetail.html', context)
```
Edit: (For future reference)
I decided to modify the tag attribute and convert CharField to ModelChoiceField, which seems to fix the issue.
Updated Class:
class EnglishTagForm(forms.Form):
tag = forms.ModelChoiceField(queryset=ClassTag.objects.filter(
agentId=Agent.objects.get(name='English Chowdhury')),
empty_label=None, widget=forms.Select(
attrs={'class':'form-control'}))
Please remove the list comprehension from Line 2. So that,
tag_choices = [(x.tagName, x.tagName.upper()) for x in ClassTag.objects.filter(
agentId=Agent.objects.get(name='English Chowdhury'))]
becomes
tag_choices = []

Filter only if the value is defined in Django

I have the following view:
def process(request):
if request.method == 'POST':
data = request.POST
results = Specs.objects.filter(screenGroup = data['screen_user'], storage = data['storage_user'], mSystem = data['system_user'] )
context = {'results' : results}
return render(request, 'process.html', context)
When the user inputs the three values it filters correctly, but when it just inputs one or two (or nothing), then it filters passing the value None. Is there any way to ignore the filter if it's not set?
Thanks!
EDIT:
The following code is working, but it's obviously a very unefficient way:
def process(request):
if request.method == 'POST':
data = request.POST
if(data['screen_user'] != None):
results = Specs.objects.filter(screenGroup = data['screen_user'])
elif (data['storage_user'] != None):
results = Specs.objects.filter(storage = data['storage_user'])
else:
results = Specs.objects.all()
#plus all the other options...
context = {'results' : results}
return render(request, 'process.html', context)
You can build the filter beforehand:
def process(request):
if request.method == 'POST':
data = request.POST
spec_filter = {}
for attribute in ['screenGroup', 'storage', 'mSystem']:
if attribute in data and data[attribute]:
spec_filter[attribute] = data[attribute]
results = Specs.objects.filter(**spec_filter)
context = {'results' : results}
return render(request, 'process.html', context)
NB: To use this verbatim you would have to change the names of the variables being passed in the request.POST to match those in the Specs model. I did this just to illustrate, but you can easily use the same principle with your variable names. In that case you'll have to be a bit more verbose.
It's called validating your form.. There are two ways of doing this:
create a django form and use myform.is_valid(). You can read about it in the docs
validate it yourself with a few 'if' statements (either on server side or with javascript before sending the ajax call)

Commit a variable to the next function

I just simple want to pass the emailadress from def send_username to the second def username_is_send. How do I do it? How can I pass the variable to the next def?
#csrf_protect
def send_username(request, template_name='auth/user/registration/send_username_form.html',
email_template_name='auth/user/registration/send_username_email.html',
send_username_form=SendUsernameForm, post_reset_redirect=None):
if post_reset_redirect is None:
post_reset_redirect = reverse('auth.user.registration.views.username_is_send')
if request.method == "POST":
form = send_username_form(request.POST)
if form.is_valid():
opts = {}
opts['use_https'] = request.is_secure()
opts['email_template_name'] = email_template_name
opts['request'] = request
form.send_mail_now(**opts)
return HttpResponseRedirect(post_reset_redirect)
else:
form = send_username_form()
return render_to_response(template_name, {
'form': form,},
context_instance=RequestContext(request))
def username_is_send(request, template_name='tmp/username.html'):
return render_to_response(template_name, context_instance=RequestContext(request))
Thanks!
Craphunter
You need to store the state somehow in order to pass parameters through a redirect. Multiple possibilities:
Store the mail address in the session, then read in the session variable again in the username_is_send view.
Use a GET parameter to pass the mail address.
And it's "pass", not "path". And the "def" is called (view) function.

Categories

Resources