can not send multiple select values to django view - python

I have a select and has multiple values but in the backend
knowledge_keywords list is empty
knowledge_keywords = request.POST.getlist('knowledge_keywords')
<div class="container">
<div class="input-group"> <span class="input-group-addon">
<input type="checkbox" class="form-check-input" name="key_words_check_box" value="1">
</span>
<select class="hidden" id="keywords" name="knowledge_keywords" multiple="multiple" data-role="tagsinput">
</select>
</div>
</div>

Views.py
keywords = request.POST.getlist('keywords')
in template
<select name="keywords" multiple="true">
<option value="1">Keyword 1</option>
<option value="2">Keyword 2</option>
<option value="3">Keyword 3</option>
<option value="4">Keyword 4</option>
<option value="5">Keyword 5</option>
</select>
try this and print keywords variable if it still gives an error then comment again and state what error is given, i have tried this, it is working.

Don't write form in html, reuse Django logic.
You can create a Form class:
Forms.py
from django import forms
class MyForm(forms.Form):
CHOICES = (
("option1", "option1"),
("option2", "option2"),
)
knowledge_keywords = forms.MultipleChoiceField(
widget=forms.CheckboxSelectMultiple, choices=CHOICES
)
template.html
<form method='post'>
{% csrf_token %}
{{ form.as_p }}
<input type='submit' value='submit'>
</form>
use the FormView provided by Django that help you to manage form in the view, for example:
Views.py
from django.views.generic import FormView
from forms import MyForm
class MyView(FormView):
form_class = MyForm
template_name = 'template.html'
def form_valid(self, form):
# can you access to cleaned value in the form inside
# form.cleaned_data['knowledge_keywords']
# and you can execute query or something else
return super().form_valid(form)

you can instead take all the options by jquery and put them in an input which is hidden.Then send them to backend
var SelectOptions = ''
// event listener when user submits the button
$("#buttonsubmit").click(function(){
$("#keywords option").each(function(){
SelectOptions = SelectOptions + $(this).val().trim() + ' '
});
// put the values in SearchKeyword input
$("#SearchKeyword").val(SelectOptions)
});

Related

Store dynamic choice field form from api call to be able to pass the verification in post request

I'm working on an app that can display the events coming from a google calendar.
To be able to do this, the user need to fill a form with the start date, end date, timezone and select a calendar.
I'm new to Django and it's ok to make a form with date, text, checkbox but regarding the choice field, it fail because the values are not present in the choice list.
Select a valid choice. johndoe#gmail.com is not one of the available choices.
This is normal because the values will change according to the user.
For that I'm calling the google calendar api before showing the page at GET request.
I tried to add it to the form but of course, it doesn't stay while the post method is called.
Is there a way to store the value without using the session or database?
How do you manage dynamic choice field that isn't coming from database?
Here is my code:
form.py
from django import forms
class events_filters(forms.Form):
start = forms.DateField(label='Start date')
end = forms.DateField(label='End date')
calendar = forms.ChoiceField(label='Select calendar')
timezone = forms.BooleanField(label="Show timezone")
view.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from googleapiclient.discovery import build
from google.oauth2.credentials import Credentials
from allauth.socialaccount.models import SocialApp, SocialAccount
import csv
from django.http import HttpResponse
from .forms import events_filters
# Create your views here.
# Main page
#login_required(login_url='/accounts/google/login/')
def index(request):
if request.method == "GET":
creds = create_credentials(request)
calendars = getCalendars(creds) #function to get the calendars
form = events_filters()
form.fields["calendar"].choices = calendars #tried to add the calendars to the form, it work but of course doesn't stay for the post request
return render(request, "ts_index.html", context={"calendars":calendars, 'form': form})
if request.method == "POST":
form = events_filters(request.POST)
if form.is_valid(): # Failed here because the form doesn't know the values to be validated. I would like to be able to validate the data without passing by the client to be sure that the user use an email in the list. I would also like to avoid to call the calendar api again.
parameters = {
"start_date" : form["start"] + "T00:00:00.000Z",
"end_date" : form["end"] + "T00:00:00.000Z",
"calendar_id" : form["calendar"],
}
# Use the access token to authenticate with the Google Calendar API
creds = create_credentials(request)
events = getEvents(creds, parameters["start_date"], parameters["end_date"], parameters["calendar_id"])
return render(request, "ts_input_data.html", context={'events':events, "parameters": parameters})
else :
print("Data not valid")
Html page
{% extends 'head.html' %}
{% load socialaccount %}
<!--Block content goes below-->
{% block content %}
<h1>Input data</h1>
<!-- Select the dates -->
<form method="POST" class="d-flex flex-column justify-content-center align-items-center" >
<!-- Key for CSRF -->
{% csrf_token %}
<!-- Select the agenda -->
<div class="mb-3 w-100">
<label for="calendar" class="form-label">Select calendar</label>
<select name="calendar" id="calendar_id" class="form-control">
{% for c in calendars %}
<option value=" {{ c.0 }} ">{{ c.1 }}</option>
{% endfor%}
</select>
</div>
<!-- Start date -->
<div class="mb-3 w-100">
<label for="start_id" class="form-label">Start date</label>
<input type="date" class="form-control" id="start_id" name="start">
</div>
<!-- End date -->
<div class="mb-3 w-100">
<label for="end" class="form-label">End date</label>
<input type="date" class="form-control" id="end_id" name="end">
</div>
<!-- End date -->
<div class="mb-3 w-100">
<label for="timezone" class="form-label">Show time-zone</label>
<input type="checkbox" class="form-check-input" id="timezone_id" name="timezone" checked>
</div>
<!-- Submit -->
<button type="submit" class="btn btn-primary w-100">Submit</button>
</form>
{% endblock %}

django forms print select values

I am trying to return the selected choice value from a dropdown menu in django. The option (in html) is dynamically populated from the database's model primary key.
HTML
<form class="student-ID-search" action="{% url 'new_coach_schedule' %}" method="post" >
<select class="form-control" id="student_select">
<option>Select student ID</option>
{% for student_data in students_data %}
<option value="{{ student_data.pk }}">{{ student_data.pk }}</option>
{% endfor %}
</select>
</form>
<button class="btn" type="submit" name="search_result" value="select>
<i class="fa fa-search"></i>
</button>
views.py
students_data = Student.objects.all()
search_result = NewStudentSearchForm(request.POST)
if 'search_result' in request.POST:
test_print_to_screen = search_result['student_select']
print(test_print_to_screen)
args = {'students_data': students_data}
return render(request, 'static/html/new_coach_schedule.html', args)
else:
return render(request, 'static/html/new_coach_schedule.html', args)
forms.py
class NewStudentSearchForm(forms.Form):
search_field = forms.CharField(max_length=50) # This is for something else.
student_select = forms.ModelChoiceField(queryset=Student.objects.all(), empty_label=None)
When I make use of ModelChoiceField, test_print_to_screen does not print out the selected choice that I chose in the html select box.. It prints out everything instead.
EG:
<select name="student_select" id="id_student_select">
<option value="5">Student object (5)</option>
<option value="6">Student object (6)</option>
<option value="7">Student object (7)</option>
<option value="8">Student object (8)</option>
<option value="9">Student object (9)</option>
<option value="10">Student object (10)</option>
<option value="11">Student object (11)</option>
<option value="12">Student object (12)</option>
<option value="13">Student object (13)</option>
</select>
How can I go about in my forms.py so that when i select the value in my browser, it will return / print out the selected choice back to me?
Update
As per the comments, I updated my views.py file to include cleaned_data as follows:
if 'search_result' in request.POST:
search_result = NewCoachSearchForm(request.POST)
print(search_result)
if search_result.is_valid():
test = search_result.cleaned_data['student_select']
print(test)
else:
print(search_result.errors)
However, this produces a stacktrace error:
<ul class="errorlist"><li>student_select<ul class="errorlist"><li>This field is required.</li></ul></li></ul>
When using Django forms, please call form's is_valid() method and then if it is valid use cleaned_data attribute to access submitted values.
students_data = Student.objects.all()
search_result = NewStudentSearchForm(request.POST)
if search_result.is_valid():
cd = search_result.cleaned_data
selected_student = cd['student_select'] # Here you get Student instance

How to get select field text from html form in django?

I have created a form with select field in template ehrinfo.html
<form action="{% url 'ehrs:compcreate' %}" method="GET">
<select>
<option value="Vital Signs">Vital Signs</option>
<option value="Cancer Signs">Cancer Signs</option>
</select><br><br>
<input type="submit" value="Select Template" class="addehr">
</form>
I have defined form class as:
class templateselect(forms.Form):
CHOICES = (
('Vital Signs', 'Vital Signs'),
('Cancer Signs', 'Cancer Signs'),
)
template = forms.ChoiceField(widget=forms.Select, choices=CHOICES)
Now I want to get selected text from this form in view compcreate. So I used:
def compcreate(request):
if request.method == 'GET':
form = templateselect(request.GET)
print("a")
if form.is_valid():
print("b")
template = str(form.cleaned_data["template"])
but it cant get past the if form.is_valid(): part as 'a' is printed but 'b' is not printed on console. What is the problem? How can I get the selected text in compcreate()?
The proper way to render your form would be to pass it in to your template via the context object and change your template. For example:
<form action="{% url 'ehrs:compcreate' %}" method="GET">
{{ form.as_p }}<br><br>
<input type="submit" value="Select Template" class="addehr">
</form>
If you want to stick with your current setup, looking at the html produced by the previous solution suggests that adding a name (equal to the name of your field in the Form class declaration) to your select field should also work:
<form action="{% url 'ehrs:compcreate' %}" method="GET">
<select name="template">
<option value="Vital Signs">Vital Signs</option>
<option value="Cancer Signs">Cancer Signs</option>
</select><br><br>
<input type="submit" value="Select Template" class="addehr">
This approach works with ModelForm and POST request:
def compcreate(request):
if request.method == 'POST':
form = templateselect(request.POST)
if form.is_valid():
ts = form.save(commit=False)
print(ts.template)
Let me know if it works in your case.

Django check if checkbox is selected

I'm currently working on a fairly simple django project and could use some help. Its just a simple database query front end.
Currently I am stuck on refining the search using checkboxes, radio buttons etc
The issue I'm having is figuring out how to know when a checkbox (or multiple) is selected. My code so far is as such:
views.py
def search(request):
if 'q' in request.GET:
q = request.GET['q']
if not q:
error = True;
elif len(q) > 22:
error = True;
else:
sequence = Targets.objects.filter(gene__icontains=q)
request.session[key] = pickle.dumps(sequence.query)
return render(request, 'result.html', {'sequence' : sequence, 'query' : q, 'error' : False})
return render(request, 'search.html', {'error': True})
search.html
<p>This is a test site</p></center>
<hr>
<center>
{% if error == true %}
<p><font color="red">Please enter a valid search term</p>
{% endif %}
<form action="" method="get">
<input type="text" name="q">
<input type="submit" value="Search"><br>
</form>
<form action="" method="post">
<input type='radio' name='locationbox' id='l_box1'> Display Location
<input type='radio' name='displaybox' id='d_box2'> Display Direction
</form>
</center>
My current idea is that I check which checkboxes/radio buttons are selected and depending which are, the right data will be queried and displayed in a table.
So specifically:
How do I check if specific check-boxes are checked? and how do I pass this information onto views.py
Radio Buttons:
In the HTML for your radio buttons, you need all related radio inputs to share the same name, have a predefined "value" attribute, and optimally, have a surrounding label tag, like this:
<form action="" method="post">
<label for="l_box1"><input type="radio" name="display_type" value="locationbox" id="l_box1">Display Location</label>
<label for="d_box2"><input type="radio" name="display_type" value="displaybox" id="d_box2"> Display Direction</label>
</form>
Then in your view, you can look up which was selected by checking for the shared "name" attribute in the POST data. It's value will be the associated "value" attribute of the HTML input tag:
# views.py
def my_view(request):
...
if request.method == "POST":
display_type = request.POST.get("display_type", None)
if display_type in ["locationbox", "displaybox"]:
# Handle whichever was selected here
# But, this is not the best way to do it. See below...
That works, but it requires manual checks. It's better to create a Django form first. Then Django will do those checks for you:
forms.py:
from django import forms
DISPLAY_CHOICES = (
("locationbox", "Display Location"),
("displaybox", "Display Direction")
)
class MyForm(forms.Form):
display_type = forms.ChoiceField(widget=forms.RadioSelect, choices=DISPLAY_CHOICES)
your_template.html:
<form action="" method="post">
{# This will display the radio button HTML for you #}
{{ form.as_p }}
{# You'll need a submit button or similar here to actually send the form #}
</form>
views.py:
from .forms import MyForm
from django.shortcuts import render
def my_view(request):
...
form = MyForm(request.POST or None)
if request.method == "POST":
# Have Django validate the form for you
if form.is_valid():
# The "display_type" key is now guaranteed to exist and
# guaranteed to be "displaybox" or "locationbox"
display_type = request.POST["display_type"]
...
# This will display the blank form for a GET request
# or show the errors on a POSTed form that was invalid
return render(request, 'your_template.html', {'form': form})
Checkboxes:
Checkboxes work like this:
forms.py:
class MyForm(forms.Form):
# For BooleanFields, required=False means that Django's validation
# will accept a checked or unchecked value, while required=True
# will validate that the user MUST check the box.
something_truthy = forms.BooleanField(required=False)
views.py:
def my_view(request):
...
form = MyForm(request.POST or None)
if request.method == "POST":
if form.is_valid():
...
if request.POST["something_truthy"]:
# Checkbox was checked
...
Further reading:
https://docs.djangoproject.com/en/1.8/ref/forms/fields/#choicefield
https://docs.djangoproject.com/en/1.8/ref/forms/widgets/#radioselect
https://docs.djangoproject.com/en/1.8/ref/forms/fields/#booleanfield
In models :
class Tag:
published = BooleanField()
(...)
In the template:
{% for tag in tags %}
<label class="checkbox">
<input type="checkbox" name="tag[]" value="" {% if tag.published %}checked{% endif %}>
</label>
{% endfor %}
Assuming you are sending the form as a POST, the values of the selected checkboxes are in request.POST.getlist('tag').
For example :
<input type="checkbox" name="tag[]" value="1" />
<input type="checkbox" name="tag[]" value="2" />
<input type="checkbox" name="tag[]" value="3" />
<input type="checkbox" name="tag[]" value="4" />
Say if 1,4 were checked,
check_values = request.POST.getlist('tag')
check_values will contain [1,4] (those values that were checked)
{% for tag in tags %}
<label class="checkbox">
<input type="checkbox" name="tag[]" value=""
{% if tag.published %}checked{% endif %}>
</label>
{% endfor %}
<input type="checkbox" name="tag[]" value="1" />
<input type="checkbox" name="tag[]" value="2" />
<input type="checkbox" name="tag[]" value="3" />
<input type="checkbox" name="tag[]" value="4" />

django poplulate html form

How to set the html form fields without using django-forms.
If you do not wish to use django.forms, but get data from a model and display it into a html form, you could do something like this:
views.py
from django.shortcuts import render_to_response, redirect
from myApp.models import MyModel
def editForm(request, model_pk):
model = MyModel.objects.get(pk=model_pk)
return render_to_response('formUpdate.html',{ 'model' : model })
def updateForm(request, model_pk):
model = MyModel.objects.get(pk=model_pk)
model.firstname = request.POST['firstname']
model.lastname = request.POST['lastname']
model.save()
return redirect('home', message='your name has been updated')
template - formUpdate.html
{% extends "base.html" %}
{% block content %}
<form action="/updateForm/{{ model.id }}/" method="post">
First name: <input type="text" name="firstname" value="{{ model.firstname }}" /><br />
Last name: <input type="text" name="lastname" value="{{ model.lastname }}" /><br />
<input type="submit" value="submit" />
</form>
{% end block %}
models.py
from django.db import models
class MyModel(models.Model):
firstname = models.CharField(max_length=20)
lastname = models.CharField(max_length=20)
urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^$', 'views.home', name="home"),
(r'^editForm/(?P<model_pk>\d+)/$', 'views.editForm'),
(r'^updateForm/(?P<model_pk>\d+)/$', 'views.updateForm'),
)
This is very similar to how forms are processed in PHP or similar, the model is passed into the template where the existing values are rendered. The id or pk (primary key) of the model is passed to the view via the URL and then updated values then returned to the storing view in the POST data where they can be retrieved and the updated values stored in the database.
One of the beauties of Django is how it balances speed of development with plugability - pretty much any of it's parts can be replaced or altered.
Having said this, is there a reason why you don't want to use django.forms? To my understanding a form simply performs most of the hard work in the example above for you, this is what django.forms are for. They also have other features, to help prevent malicious access of your web app, for example, OOTB. It is fairly easy to create ajax helper methods to retrieve and update them also.
You can do that as you would create a normal form in html. Just be careful to place the {% csrf_token %}. And the name of the input in the form, as they will be used in the view.
Eg:
<form method="post" action="#the url for the view">
{% csrf_token %}
...
...
<!-- fields that you want Eg: -->
<label for="username">User name:</label>
<input type="text" name="username" id="username" />
...
...
<input type="submit" value="Submit" />
</form>
Hope this helped.

Categories

Resources