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
Related
So i'm trying to do a filter with django, to filter the items on the main page. A little context:
An item can be assigned to a user or not. I want a filter, to see what items are assigned and which items aren't.
This is my function in views.py:
class ItemsView(ListView):
template_name = 'inventory/items.html'
context_object_name = 'items_list'
def get_queryset(self):
if (self.request.user.is_authenticated):
if self.request.method == "get":
searched = self.request.GET.get('searched')
if searched == "None":
return Item.objects.filter(assigned_user__isnull=True, company=getCompany(self.request.user))
else:
return Item.objects.filter(assigned_user__isnull=False, company=getCompany(self.request.user))
else:
return Item.objects.filter(company=getCompany(self.request.user))
And this is from my items.html:
<form method="post" action="/items">
{% csrf_token %}
<select name="item_filter">
<option value="None">Not Checked In</option>
<option value="Checked_In">Checked In</option>
</select>
<input type="submit" value="filter">
</form>
So basically what i want is, that the user can pick one of the two choices in the dropdown-menu, and the items should be listed based on the choice he made.
When i use this form and click the submit button, the screen gets white and in my console, the error
Method Not Allowed (POST): /items/ appears. Has this something to do with the fact i'm using the generic.ListView for my view?
Thank you
in list view is POST not allowed. But you dont need it:
In template:
<form action="/items">
<select name="item_filter">
<option value>Not Checked In</option>
<option value="Checked_In">Checked In</option>
</select>
<input type="submit" value="filter">
</form>
in view:
class ItemsView(ListView):
... # any staff
def get_queryset(self):
query = {'company':getCompany(self.request.user)}
if (self.request.user.is_authenticated):
query['assigned_user__isnull'] = bool(self.request.GET.get('item_filter'))
return Item.objects.filter(query)
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)
});
there is a input and select with options in form tag. i want to get input value and option that entered. and i will do somethings on backend with python that value and option than i will return a result to website. but i dont use to forms.py. how can i do? is it possible?
<form action="" method="post">
{% csrf_token %}
<input type="text" name="getinputValue">
<select name="">
<option value="1"></option>
<option value="2"></option>
<option value="3"></option>
</select>
<button type=""class=""></button>
<p>{{result}}</p>
</form>
So, from what I understanding in your question, you want to retrieve the data from the form in your views and do something with it. You will have to give your <select> a name attribute so that you can reference it in your views.
<select name="level">
<option value="1"></option>
<option value="2"></option>
<option value="3"></option>
</select>
In your views, one of the ways you can retrieve this data is by:
def options_view(request):
level = request.POST.get('level') # get name of option as specified in the <select> tag
# here you can do something with it
print(level)
return render(request, 'home.html', {'level': level})
This is one way to do it.
I have a list of stops:
<select name="dropdown">
{% for stop in stop_list %}
<option value ="{{ stop.name }}">{{ stop.name }}</option>
{% endfor %}
</select>
and a Stops model where one of the attributes is name.
I also have a method find_direction() in my views.py that requires a stop.location input.
How do I record the value of the selected stop.name so I can then get the stop.location to use in views.py?
Thanks!
Currently my method is:
def find_direction(request, stop1name, stop2name):
stop1 = get_object_or_404(Stops, name=stop1name)
stop2 = get_object_or_404(Stops, name=stop2name)
which gives the error: find_direction() missing 2 required positional arguments: 'stop1' and 'stop2name'.. How do I make it record these two variables correctly from the selected drop down list?
Using forms but for some reason..
print(request.GET.get("stop1id", "default_value"))
print(request.GET.get("stop2id", "default_value"))
print(request.method)
print(request.POST.dict())
print(request.GET.dict())
print(request.body)
all return empty
In light of your update, you will most like want to pass the data in a request:
def find_direction(request):
stop1 = get_object_or_404(Stops, name=request.POST.get("stop1name","default_value"))
stop2 = get_object_or_404(Stops, name=request.POST.get("stop2name","default_value"))
This assumes you are sending a POST request from a form back to the server with the stop name data. The dictionary keys stop1name and stop2name should match the names as they are set in your form:
<form action="/get_stop_locations">
<select name="stop1name">
{% for stop in stop_list %}
<option value ="{{ stop.name }}">{{ stop.name }}</option>
{% endfor %}
</select>
<select name="stop2name">
{% for stop in stop_list %}
<option value ="{{ stop.name }}">{{ stop.name }}</option>
{% endfor %}
</select>
</form>
If you are curious, you were receiving an error because positional arguments for django views are set up as captured bits of a url:
urls.py
urlpatterns = patterns('django_app.views',
url(r'^get_stop_locations/(\w+)/(\w+)$','positional_get_locations'),
)
views.py
def positional_get_locations(request,stop1name,stop2name):
stop1 = get_object_or_404(Stops, name=stop1name)
stop2 = get_object_or_404(Stops, name=stop2name)
Django views requires one argument by default which will store the request object. When there are more views defined, the view expects more arguments to be provided by the url handler. If the url is not set up to pull as many arguments as possible in your urls.py file, you will see this error.
For your case, this requires setting up some tricky URLs however on the client side and I wouldn't recommend it. See this example in the DJango Docs for more information on positional arguments in Django views.
EDIT:
In response to your MultiValueDictKeyError, try:
def find_direction(request):
stop1 = get_object_or_404(Stops, name=request.POST.get("stop1name","default_value"))
stop2 = get_object_or_404(Stops, name=request.POST.get("stop2name","default_value"))
If you have your dropdown located in a form like this:
<form method="post" action="">
<select name="dropdown">
{% for stop in stop_list %}
<option value ="{{ stop.name }}">{{ stop.name }}</option>
{% endfor %}
</select>
<input type="submit" />
</form>
You can get the value by defining the following in your views:
def post(self, request, *args, **kwargs):
if 'dropdown' in request.POST:
dropdown_val = request.POST.get('dropdown', False)
I've a custom template to render my form in my Django website. This code renders the ChoiceFields:
<select id="{{ "id_"|add:field.html_name }}"
class="form-control"
name="{{ field.html_name }}">
{% for id, name in field.field.choices %}
<option value="{{ id }}"
{% if field.value|default_if_none:"" == id %}
selected="selected"
{% endif %}
>{{ name }}</option>
{% endfor %}
</select>
This code works perfectly, when the ChoiceField does not have an initial value. If I sumbit the form, but there's an error in the form (sp I get back to my form, and all the data is in there as I submitted it), the correct choice get the selected="selected" attribute, so it works perfectly fine.
But when I set the default value for the form in my Django view (correctly in the form's init() function, like this: self.fields['card_type'].initial = self.card.card_type_id), this stops working.
If I put manually somewhere in my template the form.value variable it displays the correct integer. In the id, name for-loop there's the same id value. These do not have any whitespace ot something else there. But the code does not works, does not equals to true the self.fields['card_type'].initial = self.card.card_type_id condition.
If I modify the previous code, to print the id, and the field.value instead of the {{name}}, like this: ({{id}}-{{ field.value }}), the following HTML code'll be generated:
<select id="id_card_type" class="form-control" name="card_type">
<option value="3">(3-2)</option>
<option value="2">(2-2)</option>
<option value="1">(1-2)</option>
</select>
There's the id, which is 1, 2, and 3! There's the form.value, which is 2! But there isn't any selected="selected"... Why not working?
Thanks!