Passing Variable (View --> Template --> View) - python

Problem: I want to generate a random number, and ask the user to calculate the addition of these two. Then, I want to evaluate the number and see if the solution is correct.
My issue: I can do everything except the evaluation bit, as the values of the random numbers change!
HTML file:
<p> What is {{ a }} + {{ b }} ? </p>
<form action="{% url 'form_handle' %}" method="POST">{% csrf_token %}
{{form.as_p}}
<button type="submit">Submit</button>
</form>
FORM file:
class MyForm(forms.Form):
num1 = forms.CharField(max_length=20)
VIEW file:
def form_handle(request):
if request.method == 'POST':
form = MyForm(request.POST) # if post method then form will be validated
if form.is_valid():
cd = form.cleaned_data
num1 = cd.get('num1')
#num2 = cd.get('num2')
#result = cd.get('result')
if float(num1) == float(a + b):
# give HttpResponse only or render page you need to load on success
return HttpResponse("Good job!")
else:
# if sum not equal... then redirect to custom url/page
return HttpResponseRedirect('rr/') # mention redirect url in argument
else:
a = random.randrange(5,10);
b = random.randrange(10,20);
form = MyForm() # blank form object just to pass context if not post method
return render(request, "rr.html", {'form': form, 'a': a, 'b':b})
The error I get is "local variable 'a' referenced before assignment". I did try and change initialisation of a and b, and put the code right after the function declaration but that did not work either, as the function would compare the numbers (a + b) with another set of randomly generated numbers
Any help is much appreciated, or perhaps a new approach to this problem. Do note that I am a beginner in Python though

You can try to store a and b in session data:
def form_handle(request):
if request.method == 'POST':
form = MyForm(request.POST) # if post method then form will be validated
if form.is_valid():
cd = form.cleaned_data
num1 = cd.get('num1')
#num2 = cd.get('num2')
#result = cd.get('result')
a = request.session.get('a', 0)
b = request.session.get('b', 0)
if float(num1) == float(a + b):
# give HttpResponse only or render page you need to load on success
return HttpResponse("Good job!")
else:
# if sum not equal... then redirect to custom url/page
return HttpResponseRedirect('rr/') # mention redirect url in argument
else:
a = random.randrange(5,10);
b = random.randrange(10,20);
request.session['a'] = a
request.session['b'] = b
form = MyForm() # blank form object just to pass context if not post method
return render(request, "rr.html", {'form': form, 'a': a, 'b':b})

Related

django: problem with ajax request sent to ModelFormset template

I am trying to pass user data from one template inside of another template. For this I use an ajax request, as well explained here How do I integrate Ajax with Django applications?
although no error shows up, nothing gets pulled.
here is what my model formset view look like inside of template 1:
def New_Sales(request):
#context = {}
form = modelformset_factory(historical_recent_data, fields=('id','Id', 'Date','Quantity', 'NetAmount', 'customer_name'))
if request.method == 'GET':
formset = form(queryset= historical_recent_data.objects.none())
#blank_form = formset.empty_form
elif request.method == 'POST':
formset = form(request.POST)
#blank_form = formset.empty_form
if formset.is_valid():
request.session['sale'] = request.POST.get('sale')
for check_form in formset:
check_form.save()
quantity = check_form.cleaned_data.get('Quantity')
id = check_form.cleaned_data.get('Id')
update = replenishment.objects.filter(Id = id).update(StockOnHand = F('StockOnHand') - quantity)
update2 = Item2.objects.filter(reference = id).update(stock_reel = F('stock_reel') - quantity)
return redirect('/invoice/pdf/assembly/')
#else:
#form = form(queryset= historical_recent_data.objects.none())
return render(request, 'new_sale.html', {'formset':formset})
and here is the view to access template 1 data into template 2:
def generate_pdf_assembly(request):
my_company = MyCompany.objects.get(id = 1)
request = request.session.get('sale')
context = {'request' : request, 'my_company' : my_company }
print(context)
and here is the ajax request to access the data from the template (in template 2):
<h3> {{ context }} </h3>
<script>
$.ajax({
method: "GET",
url: "/new_sale.html",
sucess: function(context){
alert(context);
},
failure: function(context){
alert('got an error');
}
});
</script>
I feel like there must be an issue with the request.session in the view since no evident error gets outputed neither in log nor chrome console but I am not competent to debug it further at this point.
UPDATE: after changing context for request in tag template, the value None shows up, definitely an issue with the requesting
def username_exists(request):
data = {'msg':''}
if request.method == 'GET':
username = request.GET.get('username').lower()
exists = Usernames.objects.filter(name=username).exists()
if exists:
data['msg'] = username + ' already exists.'
else:
data['msg'] = username + ' does not exists.'`enter code here`
return JsonResponse(data)

Dynamic ChoiceField unable to be validated in form

I have a form that's being given a dictionary of selection, it populates it correctly but on form submit it is not valid. When attempting to print errors, non_field_errors there are just blanks. When I am redirected to the form, now the choice field is populated by one choice and the csrf token from previous submit.
I've tried assigning choices in different ways such as self.fields['calendar'] = forms.ChoiceField(choices=choice_list) directly assign in a different way. self.fields['calendar'].choices = choice_list, a custom validator that ignores the validation, and inline debugging.
Form model:
class CalendarSelectionForm(forms.Form):
calendar = forms.ChoiceField(label="Calendar")
def __init__(self, calendars=None, *args, **kwargs):
super(CalendarSelectionForm, self).__init__(*args, **kwargs)
choice_list = [(calendar_id, calendar_name) for calendar_id, calendar_name in calendars.items()]
if calendars:
self.fields['calendar'].choices = choice_list
View:
if request.method == "POST":
print(request.POST)
cal_sync_form = CalendarSelectionForm(request.POST)
print("Non-field errors " + str(cal_sync_form.non_field_errors()))
print("Reg form errors " + str(cal_sync_form.errors))
# print("Field val " + str(cal_sync_form.calendar))
print("Field data " + str(cal_sync_form.data))
print("Field fields " + str(cal_sync_form.fields) + " Form is " + str(cal_sync_form.is_valid()))
if cal_sync_form.is_valid():
data = cal_sync_form.cleaned_data
print(data)
return render(request, 'management/gcal_sync_dashboard.html')
else:
return render(request, 'management/acct_select.html', {'form': cal_sync_form})
Form template:
<form class="form-import" action="/manage/gcal/sync/" method="post" id = "">
{% csrf_token %}
{{ form.calendar }}
{{ form.errors }}
{{ form.non_field_errors }}
<div class="push clearfix"></div>
<div class="col-sm-6 no-pad push"><input class="btn btn-brand btn-little button filson push-half" type="submit" value="Select email"><i class="fa fa-plus"></i></input>
</div>
</form>
The goal is to validate a posted form, the current print statements print out
<QueryDict: {'csrfmiddlewaretoken': ['sJHE8JJAzmeS0nRjaYZg5KdMlevJiInYY0G4YFJeITH1cVjciIdR1Dq1N28loUIL'], 'calendar': ['email#email.io']}>
Non-field errors
Reg form errors
Field data {}
Field fields OrderedDict([('calendar', <django.forms.fields.ChoiceField object at 0x117323080>)]) Form is False
In your view, you make a call to the CalendarSelectionForm constructor with request.POST as first positional argument. So that means that you call the __init__ function, and request.POST is passed as the calendars parameter.
You can fix this by constructing your form with named parameters. You furthermore will need to pass the same parameter to calendars as you did when you rendered the form with the GET request, since otherwise the choices do not per se match, and the user might have picked an option that is in that case not available during the POST request. Like:
if request.method == 'POST':
cal_sync_form = CalendarSelectionForm(calendars=my_calendars, data=request.POST)
# ...
with my_calendars the same value you pass when you constructed the form in the GET case.

invalid django form makes is_valid method always return false

My django form is invalid and so the .is_valid method never returns true. As a result, I am getting an "Expected HttpResponse but received None" type of error because my code never executes what is within the if-condition. I am wondering how to make my form valid. I am new to django so I am probably missing something obvious. Here is my code:
views.py
template_name1 = 'multiplication/detail.html'
template_name2 = 'multiplication/multiplied.html'
class myForm(forms.Form):
quantity1 = forms.IntegerField(required=False)
quantity2 = forms.IntegerField(required=False)
form = myForm()
def get(request):
return render(request,template_name1,{'form': form} )
def multiply_two_integers(x,y):
return x*y
def post(request):
if (form.is_valid()):
x = request.POST.get('quantity1')
y = request.POST.get('quantity2')
product = multiply_two_integers(x, y)
return render(request, template_name2, {'form': form, 'product':
product })
template_name1
<h1>Multiplication Function</h1>
<form action = "{% url 'multiplication:post' %}" method = "post">
{{ form.as_p }}
{% csrf_token %}
<input type = "submit" value ="Multiply">
<!--<button type="submit"> Multiply </button>-->
<h1>{{product}}</h1>
</form>
template_name2
<h1>{{product}}</h1>
urls/multiplication
from django.urls import path
from multiplication import views
app_name = 'multiplication'
urlpatterns = [
# /multiplication/
path('', views.get, name = 'get'),
path('multiplied', views.post, name='post')
]
This code is very strange. You seem to have a set of functional views, but are trying to randomly use some concepts from class-based views.
The reason why your form is not valid is because you never pass any data to it; an unbound form cannot be valid. You should not be instantiating the form outside of a view; you need to do it in the view, and when the request is a POST you should pass the POST data to it.
In function-based views you should not define separate functions for get and post. Combine them, as sown in the Django docs.
There is another point that you have missed about the error message; your reaction to it telling you that you have not returned a response if the form is invalid is to ask "why isn't it valid", but you should also do what it says and return a response in this case; the form will sometimes be actually invalid, and you should deal with this case.
Finally, to get the data from the form you should use form.cleaned_data, not request.POST.
def multiply_two_integers(x,y):
return x*y
def my_view(request):
if request.method == 'POST':
form = MyForm(request.POST)
if (form.is_valid()):
x = form.cleaned_data['quantity1']
y = form.cleaned_data['quantity2']
product = multiply_two_integers(x, y)
return render(request, template_name2, {'product': product })
else:
form = MyForm()
return render(request,template_name1,{'form': form} )

Django: How to pass variable on form submit

I have a django 1.6.11 form (views.py):
def posneg_nlp(request):
sys_project_name = request.GET.get('project', 'graph') # here oll is ok, it can get correct project value
success = False
monitoring_words = ''
pos_features = ''
neg_features = ''
date_saved = datetime(2015, 7, 29)
print('posneg_nlp form')
print("posneg_nlp request.GET.get('sys_project_name', 'graph')", request.GET.get('project', 'graph'))
if request.method == 'POST':
posnegnlp_form = PosnegnlpForm(request.POST)
if posnegnlp_form.is_valid():
print('posneg_nlp form is_valid')
success = True
sys_project_name = sys_project_name
# here it cannot get project value, it replaced with default:
print("posneg_nlp form is_valid request.GET.get('sys_project_name', 'graph')", request.GET.get('project', 'graph'))
print("sys_project_name ", sys_project_name)
monitoring_words = posnegnlp_form.cleaned_data['monitoring_words']
pos_features = posnegnlp_form.cleaned_data['pos_features']
neg_features = posnegnlp_form.cleaned_data['neg_features']
print('pos_features:', pos_features, 'neg_features:', neg_features)
posneg_nlp_filter(sys_project_name, pos_features, neg_features, db_collection=Vkwallpost)
#get_likes_wallposts_by_owner_id(typeobject='post', owner_id=None, item_id=None, filter_posts='likes')
else:
posnegnlp_form = PosnegnlpForm()
success = False
ctx = {'posnegnlp_form': posnegnlp_form, 'sys_project_name': sys_project_name, 'monitoring_words': monitoring_words,
'pos_features': pos_features, 'neg_features': neg_features, 'success': success}
return render_to_response('choose_nlp_filter.html', ctx, context_instance = RequestContext(request))
This is the second form among two. From first form i pass a variable sys_project_name to this form via template:
<div class="rowSubmit">
<a style="outline: medium none;" hidefocus="true" href="{{ DOMAIN_URL }}/post/choose_nlp_filter/?project={{ sys_project_name }}" class="btn btn-right"><span class="gradient">К шагу 2. Выбор фильтров </span></a>
</div>
When i print current value of sys_project_name in form function posneg_nlp(request) above it shows correct value request.GET.get('project', 'graph') equal to graph2 (happens on form render).
But after that after if posnegnlp_form.is_valid(): it stops to see it and request.GET.get('project', 'graph') shows value in case it not found, equal to "graph".
So, how to pass variable and dont allow to rewrite it?
In the first case, the view is responding to an http GET request, so request.GET contains your project parameter. When the form is submitted, now the view is responsing to an http POST request, and request.POST contains the form data. In the latter case, if you want request.GET to still contain the 'project' parameter, then you can pass it via the form action parameter in your form tag:
form action="/some/url/?project={{ sys_project_name }}"

upload file to custom directory in django PYTHON

i have custom form for which i need to upload the image to some directory , below is the code
views function
def user_profile(request):
if request.method == 'POST':
form = ImageForm(request.POST, request.FILES)
if form.is_valid() and form.is_multipart():
new_user = save_file(request.FILES['image'])
return HttpResponse(new_user)
else:
form = ImageForm()
return render_to_response('user_profile.html', { 'form': form })
def save_file(file, path='home/ghrix/ghrixbidding/static/images/'):
''' Little helper to save a file
'''
filename = file._get_name()
fd = open('%s/%s' % (MEDIA_ROOT, str(path) + str(filename)), 'wb')
for chunk in file.chunks():
fd.write(chunk)
fd.close()
and below is the form:
<form method="POST" class="form-horizontal" id="updateform" name="updateform" enctype="multipart/form-data" action="/user_profile/">{% csrf_token %}
<input type="file" id="fileinput" name="fileinput" />
<button class="btn btn-gebo" type="submit">Save changes</button>
</form>
but am getting this error :
The view userprofile.views.user_profile didn't return an HttpResponse object.
The error says that your view is not returning any HttpResponse. There is one case that it's possible -
def user_profile(request):
if request.method == 'POST':
form = ImageForm(request.POST, request.FILES)
if form.is_valid() and form.is_multipart():
new_user = save_file(request.FILES['image'])
return HttpResponse(new_user)
# ------^
# There is not else check. It's possible that the if condition is False.
# In that case your view is returning nothing.
else:
form = ImageForm()
return render_to_response('user_profile.html', { 'form': form })
Regarding that error, the problem is in your view: if your form is invalid, you are not returning a response to the client:
def user_profile(request):
if request.method == 'POST':
form = ImageForm(request.POST, request.FILES)
if form.is_valid():
new_user = save_file(request.FILES['image'])
return HttpResponse(new_user)
else:
form = ImageForm()
# *** Unindented
return render_to_response('user_profile.html', { 'form': form })
also (I don't have much experience with file uploads) but I don't think you need the is_multipart check - it may be causing your form to appear invalid.

Categories

Resources