Django - POST get options from select - python

I have a html form that looks like this.
{% url 'myapp:myapp_submit' as submit %}
<form name='main' method="POST" action={{submit}}>
{% csrf_token %}
<select class='form-control' size=10 id="test" name='test' multiple>
<option>Test</option>
</select>
<input type="submit"/>
</form>
and url.py
from . import views
app_name = 'myapp'
urlpatterns = [
url(r'^$', views.myapp, name='myapp'),
url(r'results/$', views.myapp_submit, name='myapp_submit')
]
and views.py
def myapp_submit(request):
print request.POST
The only thing I get back is
<QueryDict: {u'csrfmiddlewaretoken'...]}>
How do I get back the options held in the select tag? I would use the model/view form here but I'm doing some very crazy things with JS to constantly update the options available.
UPDATE
I have used:
request.POST.getlist('test')
But it will only return ['Test'] If I highlight it with my mouse. I simply want all the options under the select tag. ex.
<select class='form-control' size=10 id="test" name='test' multiple>
<option>Test1</option>
<option>Test2</option>
<option>Test3</option>
<option>Test4</option>
</select>
and
###Not sure if it's still getlist method
>>request.POST.getlist('test')
['Test','Test2','Test3','Test4']

Try to change your views.py:
def myapp_submit(request):
request.POST.getlist('test[]')

Because you say you're doing weird things with Js, you can first check the POST request from your browser and what parameters you send with it.

A month ago I solved this problem, you need to use name in your option tag
Example:
<select name="status">
<option name="status">
and see result in your view.

Related

How to render json data in Python Django App

I am new to Python . I am trying to create a webapp from Django which will read data from Excel file and then it will show that data on webpage in a form of dropdown .
This is the structure of my web app which is I am creating
I have also created a python script which is parsing the excel data and returning the json data
import pandas
import json
# Read excel document
excel_data_df = pandas.read_excel('Test-Data.xlsx', sheet_name='Sheet1')
# Convert excel to string
# (define orientation of document in this case from up to down)
thisisjson = excel_data_df.to_json(orient='records')
# Print out the result
print('Excel Sheet to JSON:\n', thisisjson)
thisisjson_dict = json.loads(thisisjson)
with open('data.json', 'w') as json_file:
json.dump(thisisjson_dict, json_file)
This is output of this script
[{"Name":"Jan","Month":1},{"Name":"Feb","Month":2},{"Name":"March","Month":3},{"Name":"April","Month":4},{"Name":"May","Month":5},{"Name":"June","Month":6},{"Name":"July","Month":7},{"Name":"August","Month":8},{"Name":"Sep","Month":9},{"Name":"October","Month":10},{"Name":"November","Month":11},{"Name":"December","Month":12}]
This is what I am to have on html
<!DOCTYPE html>
<html>
<body>
<h1>The select element</h1>
<p>The select element is used to create a drop-down list.</p>
<form action="">
<label for="months">Choose a Month:</label>
<select name="months" id="month">
<option value="1">Jan</option>
<option value="2">Feb</option>
<option value="3">March</option>
<option value="4">April</option>
</select>
<br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
Now where I am stuck is how we can integrate this in my webapp and how we can use this Json data to create a dropdown list on my webpage.
You need to do following 3 steps.
Write a view function to see your Excel data in your HTML.
Add your view function in your urls.py file.
Create a loop in your HTML to see your months_data.
1. my_website/views.py
from django.http import Http404
from django.shortcuts import render
def get_months(request):
months_data = your_json
return render(request, 'your_html_path', {'months': months_data})
2. my_website/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.get_months),
]
3. home.html
<!DOCTYPE html>
<html>
<body>
<h1>The select element</h1>
<p>The select element is used to create a drop-down list.</p>
<form action="">
<label for="months">Choose a Month:</label>
<select name="months" id="month">
{% for month in months %}
<option value={{ month.Month }}>{{ month.Name }}</option>
{% endfor %}
</select>
<br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
Also, you can look for more information about views Writing views | Django documentation
and you can look for more information about urls URL dispatcher | Django documentation
I hope it works for you!
Why dump to json?
Use pyexcel its easy to understand the docs.
link docs
Another option is to use ajax, you can implement the excel output (json Response) in a simple way in your template. If you dont want to use pyexcel (which is in most cases sufficient) let me know, then we can get into an ajax example.
I'm not sure if you're using function or class based view, but pass your data in the context
...
context['months'] = [{"Name":"Jan","Month":1}, ...]
...
Then in the template iterate over it
...
{% for item in months %}
<select name="months" id="month">
<option value="{{ item.Month }}">{{ item.Name }}</option>
</select>
{% endfor %}
...

How can I get values from a view in Django every time I access the home page

I currently have the following view created in Django:
#login_required
def retrieve_from_db(request):
some_ids = get_some_data()
context = {'some_ids': some_ids}
return render(request, 'index.html', context)
This is my urls.py:
from django.urls import path
from . import views
app_name = 'blabla'
urlpatterns = [
path('', views.another_view, name='index'),
path('', views.retrieve_from_db, name='index'),
...
...
...
]
And this is part of my index.html
<div>
<select name="myIdList" id="myIdList">
{% for some_id in some_ids %}
<option value="{{ some_id }}">{{ some_id }}</option>
{% endfor %}
</select>
</div>
I would like to know how can I get the results from the function retrieve_from_db(). What I want is that every time I access the home page, by default the selects are populated with the result of the view.
All I have found so far on StackOverflow have been answers using forms in which the user somehow has to perform some action to trigger the POST, is there any way to do all of this without the user having to press any buttons or perform an action? simply every time the page loads, get the results of the retrieve_from_db() function defined in the view.
You can use "GET" method which is not safe for passing sensitive data!
GET should send data while rendering page.
Your views.py function to retrieve data would look like this:
#login_required
def retrieve_from_db(request, some_id):
if request.method == "GET":
some_ids = request.GET.get('some_id')
context = {'some_ids': some_ids}
return render(request, 'index.html', context)
Your HTML would look like this:
<div>
<form action="/retrieve_from_db/{{some_id}}" method="GET">
<select name="myIdList" id="myIdList">
{% for some_id in some_ids %}
<option value="{{ some_id }}">{{ some_id }}</option>
{% endfor %}
</select>
</div>
Interesting part here is, how it will pass many 'some_id' objects as you generate them from for loop.
This solution maybe is not one of the most elegant ones, but should pass data without user interference.

How to append two separate forms to the end of a url in Django

I am attempting to create a django web app, and I'm running into an issue with forms. I have a simple index.html set up that has two separate regular html forms on the page. One for filtering and the other for sorting. Currently, I can get either filtering, or sorting to work, but not both at the same time. I think this is because I'm missing a fundamental understanding of django somewhere. Yes, I've done the tutorials.
I've attempted manually appending the URL to my url config, but that didn't work as intended.
<form action="" method="get">
{% for filter in view.all_filters %}
<label>
<input type="checkbox" name="filter" value="{{ filter }}">
{{ filter }}
</label>
{% endfor %}
<input type="submit" value="Apply Filters">
</form>
<form action="." method="get">
<label>
Sort By
<select name="order_by">
<option value="name">Name</option>
<option value="description">Description</option>
<option value="cvssBaseScore">Cvss Base Score</option>
<option value="cvssV3BaseScore">Cvss V3 Base Score</option>
</select>
</label>
<input type="submit" value="Submit">
</form>
I would like the url to be able to append something like ?filters=one&filters=two&order_by=name or something as such.
The question is not really related to Django but rather to how HTML forms work:
A <form> element encapsulates all the data (<input>s) that it submits, so if you put two separate forms in your HTML page, then you intentionally want only one of the forms to be submitted with its data.
Just put both your inputs (the filter and the order_by inputs) inside the same <form> element so that both are submitted when either of the submit buttons is clicked.

Django: Use text box data and write that text in a file

I am super new to Django and web development. Right now my objective is to create a google like interface and take the text from search box and write it to a file (in other words just want to access text data in the search box). I have created a search page like below
search.html
{% extends "header.html" %}
{% block content %}
<div style="display: flex; justify-content: center;">
<img src="/static/images/logo.jpg" class="responsive-img" style='max-height:300px;' alt="face" >
</div>
<form method="get" action="">
{% csrf_token %}
<div style="display: flex; justify-content: center;">
<input type="text" name="query" placeholder="Search here..." required size="70" >
<button type="submit">Go!</button>
</div>
<button type="submit">Search</button>
</form>
{% endblock %}
views.py
from django.shortcuts import render
def index(request):
return render(request, 'search.html')
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index')
]
Please give me a hint/example of how to go forward from here ? Thanks.
Your search field looks like this:
<input type="text" name="query">
The name of the input is query. Since it's a GET form, when you submit it, you must have noticed, the url looks something like this:
/?query=<value of the input>
The part after ? is called querystring. For every request, Django maintains a dictionary of the querystring. The request object has a dictionary called GET for GET requests. If you make a POST request, Django will save the form data in a dict called POST.
To access the value of the request querystring in Django, you can do this:
query = request.GET.get('query')
If it's a POST request, you'd do the same but use the POST dictionary this time:
some_value = request.POST.get('some_key')
Full docs on this can be found at - Request and response objects.
This should do it
views.py
def index(request):
query = request.GET.get('query')
# do a check here to make sure search_term exists before attempting write
with open('/path/to/file', 'rw') as f:
f.write(query)
return render(request, 'search.html')

Django from doesn't get processed. HTTP 405 error raises

I am trying to process a post form, but I can't manage. I have prepared the form, gave the action link, set the method to post, but when I hit the submit button, nothing happens, not even an error page isn't shown by django despite my debug option is True.
Here is the form code in my template file:
<form method="post" action="{% url 'articles:stepprocess' 0 %}">
{% csrf_token %}
<p><label for="title">Title:</label>
<input name="title" id="title" type="text"/></p>
<p>
<label for="dif">Difficulty</label>
<select name="dif" id="dif">
{% if difficulties %}
{% for difficulty in difficulties %}
<option value="{{ difficulty.pk }}">{{ difficulty }}</option>
{% endfor %}
{% endif %}
</select>
</p>
<p><label for="article">Content:</label>
<textarea cols="37" rows="11" name="article" id="article"></textarea></p>
<p><input name="send" style="margin-left: 150px;" class="formbutton" value="Send"
type="submit"/></p>
</form>
My urls.py file:
from django.conf.urls import url
from .views import *
urlpatterns = [
url(r'^$', Index.as_view(), name="index"),
url(r'^new/(?P<step>[0-9]+)/$', NewArticle.as_view(), name="newarticle_continue"),
url(r'^new/', NewArticle.as_view(), name="newarticle"),
url(r'^new/process/(?P<step>[0-9]+)/$', FormManager.as_view(), name='stepprocess')
#url(r'^show/(?P<article>[0-9]+)/$'),
]
And lastly, my views.py file:
#required imports...
class FormManager(View):
def post(self, request, *args, **kwargs):
return HttpResponse(kwargs['step'])
When I hit the submit button, it gives me HTTP 405 error. I can see this error in python console but nothing shows in browser. Just blank white screen.
This was actually to test if view works properly. My final purpose is that I would like to access the post variables and redirect the page. However, HttpResponseRedirect also doesn't work. How can I fix this?
HTTP 405 error means "method not allowed"
In your case you are POSTing... the view looks like it should accept POST requests though.
The problem is your urls.py is wrong, the url you POSTed to is intercepted by the NewArticle view instead, which I guess only accepts GETs.
from django.conf.urls import url
from .views import *
urlpatterns = [
url(r'^$', Index.as_view(), name="index"),
url(r'^new/process/(?P<step>[0-9]+)/$', FormManager.as_view(), name='stepprocess')
url(r'^new/(?P<step>[0-9]+)/$', NewArticle.as_view(), name="newarticle_continue"),
url(r'^new/', NewArticle.as_view(), name="newarticle"),
#url(r'^show/(?P<article>[0-9]+)/$'),
]
Django looks at the urls in the urlconf in the order they are defined and will dispatch your request to the first one that matches.
Above I have modified the order, alternatively you could just add the $ to end of url:
url(r'^new/$', NewArticle.as_view(), name="newarticle"),
this will prevent it matching any new/* url paths.

Categories