Can't get form data in view function: Django - python

I need to submit a string to a view function via a dropdown menu and submit button.
in my template I have:
<form action="{% url 'exec_task' %}" method="post">
{% csrf_token %}
<select id="select_task" form="select_task" name="select_task">
{% for task in available_tasks %}
<option id="selected_task" value="{{ task }}">{{ task }}</option>
{% endfor %}
</select>
<input class="button" type="submit" value="Run Selected Task">
</form>
in my view function I have:
def exec_task(request):
if request.method == 'POST':
task = request.POST.get('select_task')
print(task)
getattr(tasks, task)(0)
return redirect('management')
The print(task) always comes out as None, which generates an error when I try to call it via getattr in the next line.
I've read through all the questions and tutorials I can find on this and I don't know what I'm doing wrong, but when I print the request.POST object, all I get is the csrf token. The QueryDict has nothing else in it.
Any ideas?

As discussed in comments please remove
form="select_task" from select tag.
So final select tag / html would be.
<form action="{% url 'exec_task' %}" method="post">
{% csrf_token %}
<select id="select_task" name="select_task">
{% for task in available_tasks %}
<option id="selected_task" value="{{ task }}">{{ task }}</option>
{% endfor %}
</select>
<input class="button" type="submit" value="Run Selected Task">
</form>

Related

How to get the selected value from html select with django

I would like to know if it's possible to get the selected value from a select HTML without using a submit input? Because when I hit the submit, the value selected is returned but it reloads the web page and the select goes back to it's intial state.
Here is my code to visualize better:
views.py
def index(request):
id_desi = request.POST.get('drop_desi')
return render(request, 'index.html', {'designation_liste': df.designation_liste})
index.html
<form action="{% url 'DataMat-index' %}" method="POST">{% csrf_token %}
<select name="drop_desi">
<option disabled selected value> -- select value -- </option>
{% for i in designation_liste %}
<option value="{{ i }}">{{ i }}</option>
{% endfor %}
</select>
<input type="submit" value="valider">
</form>

How to access the selected option in an select tag with Django (not using Javascript)?

I have a form that has a select tag and dynamically created options for that tag as shown below. I want to access the selected tag if it is included in the POST request as part of the form in my Python/Django code:
<form action="{% url 'newprogram' %}" method="post" novalidate>
{% csrf_token %}
TODO: Add Program to School
<select name="schooloptions">
{% for school in schools %}
<option value="{{ school.name }}">{{ school.name }}</option>
{% endfor %}
</select>
<div class="form-group">
<input autofocus class="form-control" type="text" name="programname" placeholder="">
</div>
<input class="btn btn-primary" type="submit" value="Post">
</form>
I want to select the option that the user selects from the drop-down menu as follows but it does not work:
#login_required
def newprogram(request):
if request.method == "POST":
programname = request.POST["programname"]
school = request.POST["schooloptions"].selected() #This does not work and is what I need help with
schoolobj = School.objects.get("school")
school = Program(School=schoolobj, name=programname)
school.save()
return render(request, "network/index.html")
Any thoughts as to how I can access the selected option from a select HTML tag within a form?

Django form action attribute is not working propely

I am working on app in django 1.11, on search feature. I installed elasticsearch - here all things are working.
In base.html and under url 127.0.0.1:8000 - I have form to search and I would like to keep this form here. On another hand I have search app with view, url, template - under url 127.0.0.1:8000/search/ - search is working here.
To solve this problem - search on main page and redirect on site with results I was trying to use action attribute in django form.
form in base.html
<form action="{% url 'search:search' %}" method="post">
{% csrf_token %}
<div class="input-group">
<input type="text" class="form-control" id="q" {% if request.GET.q %}value="{{ request.GET.q }}"{% endif %} name="q" placeholder="Search">
<div class="input-group-append">
<button class="btn btn-outline-primary" type="button">GO</button>
</div>
</div>
</form>
view in search app
def search(request):
q = request.GET.get('q')
if q:
posts = PostDocument.search().query('match', title=q)
else:
posts = ''
return render(request, 'search/search.html', {'posts': posts})
template with results
{% extends 'base.html' %}
{% block content %}
{% for p in posts %}
{{ p.title }}
{% endfor %}
{% endblock content %}
{% block sidebar %}{% endblock sidebar %}
You here mix up GET and POST. If the method is method="post", then the data is passed in the request, and thus ends up in the request.POST query dictionary.
If on the other hand the method is method="get", then the data ends up in the querystring of the URL. In that case, you can indeed use request.GET.
Often (not always), search queries are done with querystrings, since then a person can copy the URL and send it to another person, and that person thus can see the search results.
You can thus change the form to:
<form action="{% url 'search:search' %}" method="get">
{% csrf_token %}
<div class="input-group">
<input type="text" class="form-control" id="q" {% if request.GET.q %}value="{{ request.GET.q }}"{% endif %} name="q" placeholder="Search">
<div class="input-group-append">
<button class="btn btn-outline-primary" type="button">GO</button>
</div>
</div>
</form>

working with form in Django

This is page that designed to submit the answers of my MCQ(multiple choice question) App in Django.
{% extends 'quiz/base.html' %}
{% block content%}
<h1>You are at quiz page</h1>
<form action="{% url 'quiz:process_data' %}" method="post">
{% csrf_token %}
{% for question in question_set %}
<h3>{{question.id}}.{{question.question_text }}</h3>
{% for option in question.options_set.all %}
<input type="radio" name="choice" value="{{ option.options}}" > {{option.options}}<br>
{% endfor %}
{% endfor %}
<input type="Submit" name="Submit">
</form>
{% endblock%}
The problem is that it can only select the answer of one question. There is something wrong with my form. Thank you
<input type="radio" name="choice" value="{{ option.options}}">
by this line name of radio button will be same for each question. that's why you are able to select only one answer.
name of radio button should be different for diff. question
<input type="radio" name="choice{{question.id}}" value="{{ option.options}}">
you can use this code. In this name of radio buttons in first question will be "choices1". and you can get selected option by
request.POST.get('choice1')

How to get all the options submitted by form

How to get all the options submitted by the form in Django, this is the form which I used.
{% extends 'quiz/base.html' %}
{% block content%}
<h1>You are at quiz page</h1>
<form action="{% url 'quiz:process_data' %}" method="post">
{% csrf_token %}
{% for question in question_set %}
<h3>{{question.id}}.{{question.question_text }}</h3>
{% for option in question.options_set.all %}
<input type="radio" name="choice{{question.id}}" value="{{ option.options}}" > {{option.options}}<br>
{% endfor %}
{% endfor %}
<input type="Submit" name="Submit">
</form>
{% endblock%}
I tried selected_choice=request.POST ,but getting this as output csrfmiddlewaretokenchoice1Submitchoice3. How can I solve this? Thank you
In django request.POST is dictionary-like object, see details here.
So to obtain argument choice in view you can use following syntax:
selected_choice=request.POST.get('choice')
which return choice value or None in case this is empty.
Since request.POST is dict-like object you can use items() method to get all values and filter them:
for k, v in request.POST.items():
if k.startswith('choice'):
print(k, v)
this will print only those params with choice text in name.
selected_choice=request.POST.get('choice')
The above should work just fine, but if you're crazy, you can try this:
{% extends 'quiz/base.html' %}
{% block content%}
<h1>You are at quiz page</h1>
<form action="{% url 'quiz:process_data' %}" method="post" id= "crazyform">
{% csrf_token %}
{% for question in question_set %}
<h3>{{question.id}}.{{question.question_text }}</h3>
{% for option in question.options_set.all %}
<input type="radio" name="choice" value="{{ option.options}}" > {{option.options}}<br>
{% endfor %}
{% endfor %}
<input type="hidden" name="crazychoice" class="crazy" value="nothing">
<input type="Submit" name="Submit">
</form>
{% endblock%}
Then some JQuery:
$('#crazyform input').on('change', function() {
$(".crazy").val($('input[name=choice]:checked', '#crazyform').val())})
Everytime you click a radio button, the value of the hidden input field changes to the value of the selected radio button.
Then in your view you can:
selected_choice = request.POST.get("crazychoice", "")

Categories

Resources