How to get data from input form - python

I need to get data from input and write it to query variable. When I click to search button I need write data in query variable. How can I do that? I mean click event and write data in query.
This is my code:
views.py:
from django.http import HttpResponse
from django.shortcuts import render
def index(request):
if request.method == 'GET':
return render(request, 'index.html', context={})
# Handles the search once the submit button in the form is pressed
# which sends a "POST" request
if request.method == 'POST':
# Get the input data from the POST request
search_query = request.POST.get('search', None)
# Validate input data
if search_query and search_query != "":
try:
from googlesearch import search
except ImportError:
print("No module named 'google' found")
for j in search(search_query, tld="co.in", num=10, stop=1, pause=2):
print(j)
else:
return HttpResponse('Invalid input.')
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<form method="POST">
{% csrf_token %}
<input type="text" name="search" placeholder="some text"><br>
<button class="button" name="submit" type="submit">Search</button>
</form>
</body>
</html>
urls.py
from django.urls import path
from firstapp import views
urlpatterns = [
path('', views.index, name='home')
]
All files are in hello folder. My app namely firstapp path: C:\Users\user\Desktop\hello\firstapp
index.html path is:
C:\Users\user\Desktop\hello\firstapp\templates

We will need to change the index() function to handle POST or GET methods (refer to https://www.w3schools.com/tags/ref_httpmethods.asp for more information on GET and POST requests), by default django always listens to a GET request. You can know whether or not a method is GET by using request.method == 'GET' and request.method == 'POST' for POST.
To access the data inside the method, use request.POST.get("search", None), which basically says find the input with the name attribute from the form or if the input does not exist, return None.
So, all in all, your code should now look like this
from django.http import HttpResponse
from django.shortcuts import render
def index(request):
if request.method == 'GET':
return render(request, 'home/home.html', context={})
# Handles the search once the submit button in the form is pressed
# which sends a "POST" request
if request.method == 'POST':
# Get the input data from the POST request
search_query = request.POST.get('search', None)
# Validate input data
if search_query and search_query != "":
# Implement search functionality....
# ...
return HttpResponse(search_query)
else:
print("Invalid input")
return render(request, 'home/home.html', context={})
Now inside the app, make a folder named templates and add index.html
The index.html file should look like (to learn more about templates refer to: https://docs.djangoproject.com/en/2.2/topics/templates/):
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form method="POST">
{% csrf_token %}
<input type="text" name="search" placeholder="some text"><br>
<button class="button" name="submit" type="submit">Search</button>
</form>
</body>
</html>
my_app/templates/index.html
Also, if you look at the <form> tag, you can find a method tag which says POST. This indicates whether the data that is being submitted is a POST request.

Related

Querying an API, and displaying it's results from from form input - Django

I am not sure if I am going about this correctly, but I am not getting any errors it just reloads the page without displaying anything.
The issue could be with me trying to format the api string and input the users input there?
I also tried returning the variable as an HttpResponse, still made no difference.
Sorry just getting back into python, and just starting with Django.
Correct code should go something like this:
1.User inputs their name into the form
2. Page then displays the usersid.
Code:
views.py:
from urllib import response
from django.shortcuts import render
from django.http import HttpResponse
import requests
from .forms import SearchUser
import json
# Create your views here.
def home(response):
# data = requests.get(
# 'https://americas.api.riotgames.com/riot/account/v1/accounts/by-riot-id/ReallyBlue/NA1?api_key=RGAPI-6c5d9a2c-3341-4b0c-a0a5-7eafe46e54cf')
# userid = data.json()['puuid']
return render(response, "main/home.html", {
'form': SearchUser(), # include reference to your form
'userid': search,
# 'mmr':NA,
})
def search(response):
if response.method == "POST":
form = SearchUser(response.POST)
if form.is_valid():
n = form.cleaned_data["name"]
user = n(name=n)
user.save()
data = requests.get(
f"https://americas.api.riotgames.com/riot/account/v1/accounts/by-riot-id/'{user}'/NA1?api_key=RGAPI-6c5d9a2c-3341-4b0c-a0a5-7eafe46e54cf")
userid = data.json()['puuid']
return HttpResponse(userid)
else:
form = SearchUser()
return render(response, "main/home.html", {"userid": userid})
forms.py:
from django import forms
class SearchUser(forms.Form):
name = forms.CharField(label="Name", max_length=200)
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("", views.home, name=""),
path("", views.search, name=""),
]
home.html:
{% extends 'main/base.html'%}
{% block content %}
<h2>Valorant Ranked Checker</h2>
<form method="post" action="">
{% csrf_token %}
{{form}}
<button type="submit" name="search">
Get rank
</button>
</form>
<p><strong>{{userid}} - {{mmr}}</strong></p>
{% endblock %}
base.html:
<!DOCTYPE html>
<head>
<title>Blue's Valorant Ranked Checker</title>
</head>
<body>
<div id="content" name="content">
{% block content %}
{% endblock %}
</div>
</body>
</html>
So what you have to do is, use a single view for the url and then do the API querying inside that view. So something like:
urlpatterns = [
path("", views.search, name=""),
]
and then inside your view, you need to send the form with the context dictionary to show it in the HTML.
def search(response):
if response.method == "POST":
form = SearchUser(response.POST)
if form.is_valid():
name = form.cleaned_data["name"]
data = requests.get(
f"https://americas.api.riotgames.com/riot/account/v1/accounts/by-riot-id/{user}/NA1?api_key=*******")
userid = data.json()['puuid']
return HttpResponse(userid) # Or preferably pass onto a different view
else:
return HttpResponse("Form is not properly filled")
else:
form = SearchUser()
return render(response, "main/home.html", {"form": form})

Why does HTML/Django template execute code out of order?

This html template from my online class executes as intended, but why? It seems like it is executing out of order:
It calls my python form class using Django's syntax {{form}} to inject the blank fields for the user to fill out (name, email, textbox)
The user can enter and hit the "Submit" button
but then (confusingly) is that it seems the {{form}} class is called again with the entry information as it then successfully prints out user input to the terminal. Why is this?
html in templates.py
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.3.1/dist/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
</head>
<body>
<h1>fill out the form</h1>
<div class="container">
<form method="POST">
{{form}}
{% csrf_token %}
<input type="submit" class="btn btn-primary" value="submitme">
</form>
</div>
</body>
</html>
Form class in views.py
def form_name_view(request):
form = forms.FormName()
if request.method == "POST":
form = forms.FormName(request.POST)
if form.is_valid():
print("VALIDATION SUCCESS")
print("NAME: " + form.cleaned_data['name'])
print("EMAIL: " + form.cleaned_data['email'])
print("TEXT: " + form.cleaned_data['text'])
return render(request, 'first_app/form_page.html', {'form' : form})
Supplemental: the url that uses the html template and my forms class
from django.urls import path
from first_app import views
urlpatterns = [path('formpg', views.form_name_view, name = 'formpg')]
As mentioned in the Django form docs,
Form data sent back to a Django website is processed by a view, generally the same view which published the form. This allows us to reuse some of the same logic.
So your code is executing in the correct order:
When the page is first loaded, a GET request is made and form_name_view() is called. This creates an empty Form object and renders it into a html form with render(request, 'first_app/form_page.html', {'form' : form})
When the html form is submitted, a POST request is made and a new Form object is made with the data sent from the web browser. As in the example, you may want to direct users to another page if their submitted form is valid.

Unable to get Django HttpResponse

A little description of what i m trying to do.
I want to make a User Interface (web/HTML) through which i can send the commands to router and display the result on the Webpage/HTML.
Here's the code i m using:-
Views.py
from django.shortcuts import render
from first_app.forms import CmdForm
from django.http import HttpResponse
def index(request):
my_dict = {'insert_me': ""}
return render(request,'first_app/index.html',context=my_dict)
def form_name_view(request):
if request.method == "POST":
form = CmdForm(request.POST)
if form.is_valid():
from netmiko import ConnectHandler
devices = {
'device_type':'cisco_ios',
'ip':'192.168.50.145',
'username':'me',
'password':'12345',
'secret':'12345',
'port':'22'
}
cmd = request.POST.get('command', '')
netconnect = ConnectHandler(**devices)
#print("connection established with", devices['ip'])
output = netconnect.send_command(cmd)
return render(request,'first_app/forms.html', {'form': form,
'output':output})
else:
form = CmdForm()
return render(request,'first_app/forms.html', {'form': form})
forms.py
from django import forms
class CmdForm(forms.Form):
command = forms.CharField(label='Command to execute')
urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import include
from first_app import views
urlpatterns = [
path('Automation_page/', views.form_name_view,name='IP form'),
path('admin/', admin.site.urls),
path('', views.index,name='first'),
path('first_app/',include('first_app.urls')),
]
forms.html
<!DOCTYPE html>
{% load staticfiles %}
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>FORMS</title>
</head>
<body>
<h1> IP address form </h1>
<p>Run command:</p>
<form method="POST"> {% csrf_token %}
{{ form }}
<input type="submit" value="Run command!" />
</form><br>
{% if request.POST %}
<p>Command output:</p>
<pre>{{ output }}</pre>
{% endif %}
</body>
</html>
i am getting the error when i visit the Automation_page/
ValueError at /Automation_page/
The view first_app.views.form_name_view didn't return an HttpResponse object. It returned None instead.
Request Method: GET
Request URL: http://127.0.0.1:8000/Automation_page/
Django Version: 2.2.3
Exception Type: ValueError
Exception Value:
The view first_app.views.form_name_view didn't return an HttpResponse object. It returned None instead.
Exception Location: K:\Work\DevNet\ENV1\lib\site-packages\django\core\handlers\base.py in _get_response, line 126
Python Executable: K:\Work\DevNet\ENV1\Scripts\python.exe
Python Version: 3.7.3
Python Path:
['K:\Work\DevNet\first_project',
'K:\Work\DevNet\ENV1\Scripts\python37.zip',
'K:\Work\DevNet\ENV1\DLLs',
'K:\Work\DevNet\ENV1\lib',
'K:\Work\DevNet\ENV1\Scripts',
'c:\users\karti\appdata\local\programs\python\python37-32\Lib',
'c:\users\karti\appdata\local\programs\python\python37-32\DLLs',
'K:\Work\DevNet\ENV1',
'K:\Work\DevNet\ENV1\lib\site-packages']
Need help on this.
thanku who are willing to help
The last line needs to be moved one indent to the left, so it is hit if the form is invalid.
else:
form = CmdForm()
return render(request,'first_app/forms.html', {'form': form})
I was able to figure out the solution of my problem.
sharing it for others if they can relate. :-)
In views.py
Add the following code, with indent to first if statement.
else:
return render(request,'first_app/forms.html', {})

How do I display the console output to HTML in Django?

So I'm using Django framework to display the console output to the HTML. To execute the command, I'm using the check_output of subprocess module in Python. Which receives the input from the HTML input form. The problem is that I only see "None" on the HTML page, which is the default value of output in views file.
Below is the code of the views file and HTML file. I'm a novice in this so I'd appreciate your assistance.
Views.py
from django.shortcuts import render
from django.shortcuts import redirect
from .forms import command_form
import subprocess as sp
# Create your views here.
def welcome_page(request):
output=""
if request.method == "POST":
myform = command_form(request.POST)
if (myform.is_valid()):
execute_command = myform.cleaned_data['cmd_string']
output = sp.check_output(execute_command, shell=True)
else:
myform = command_form()
return render(request, 'ovs/welcome.html', {'output': output})
else:
return render(request, 'ovs/welcome.html', {})
welcome.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>welcome to ovs GUI</title>
</head>
<body>
<h3>Choose the option:</h3>
<form method="POST">{% csrf_token %}
Enter the command: <input type="text" name="cmd_string" id="cmd_string"/>
<input type="submit" value="Run"/>
</form>
<h3>{{ output }}</h3>
</body>
</html>
forms
from django import forms
class command_form(forms.Form):
command = forms.CharField(max_length=200)
You are not rendering the form field correctly to your HTML. You have created a command_form form and you never exploit it. However, you should use camel case name for python classes, like this CommandForm.
Inside your HTML, write this:
<form method="POST">{% csrf_token %}
Enter the command: {{ myform }}
<input type="submit" name="submit_cmd" value="Run" />
</form>
{% if output %}<h3>{{ output }}</h3>{% endif %}
{% if exit_code %}<h3>Your command returned an error: {{ error_msg }}</h3>{% endif %}
{{ my_form }} will expand, automatically, to <input type="text" ...>
Now, write your welcome_page view like this:
def welcome_page(request):
output = ""
# Initialize the form. At this point you have an unbound/invalid form
myform = command_form() # better write it as CommandForm
if request.method == "POST":
myform = command_form(request.POST)
if myform.is_valid():
# execute_command variable, should now contain the command typed by the user in the text box
execute_command = myform.cleaned_data['command']
try:
# If the return code is non-zero, CalledProcessError will be raised
output = sp.check_output(execute_command, shell=True)
except sp.CalledProcessError:
exit_code, error_msg = output.returncode, output.output
else:
# Do something when the form is not valid. Maybe add a message or something, or not implement else clause at all.
return render(request, 'ovs/welcome.html', locals())
Warning! As per the docs say:
Using shell=True can be a security hazard.
You can use REST framework to return a Response so you don't have to worry about handling it in HTML. Just install the rest_framework and do this:
from rest_framework.response import Response
return Response(data)
views.py
from django.shortcuts import render
from django.shortcuts import redirect
from test.forms import CommadForm
import subprocess as sp
def welcome_page(request):
if request.method == "POST":
myform = CommadForm(request.POST)
if myform.is_valid():
execute_command = myform.cleaned_data['command']
try:
output = sp.check_output(execute_command, shell=True)
except sp.CalledProcessError:
output = 'No such command'
else:
myform = CommadForm()
return render(request, 'ovs/welcome.html', {'output': output})
else:
return render(request, 'ovs/welcome.html')
forms.py
class CommadForm(forms.Form):
command = forms.CharField(max_length=200)

Django redirect to index view with correct URL after form submission

I am learning Django and am trying to create a form that I can submit a participant's information to the database.
I have an index view, which list all the participants:
http://127.0.0.1:8000/participants/
Clicking a button on the index will go to form submission:
http://127.0.0.1:8000/participants/add_participant/
After submitting the form, the page goes back to the index view, but the URL is not correct, it stucks at http://127.0.0.1:8000/participants/add_participant/
If I refresh the browser immediately, it will add another record to the database.
add_participant.html
<!DOCTYPE html>
<html>
<head>
<title>This is the title</title>
</head>
<body>
<h1>Add a Participant</h1>
<form id="participant_form" method="post" action="/participants/add_participant/">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="submit" value="Create Participant" />
</form>
</body>
</html>
views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.http import HttpResponse, HttpResponseRedirect
from participants.models import Participant
from .forms import ParticipantForm
# Create your views here.
def index(request):
participant_list = Participant.objects.order_by('-first_name')[:50]
context = {'participants': participant_list}
return render(request, 'participants/index.html', context)
def add_participant(request):
if request.method == 'POST':
form = ParticipantForm(request.POST)
if form.is_valid():
form.save(commit=True)
return index(request)
else:
form = ParticipantForm()
return render(request, 'participants/add_participant.html', {'form': form})
urls.py
from django.conf.urls import url
from . import views
from .models import Participant
app_name = 'participants'
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'add_participant/$', views.add_participant, name='add_participant'),
]
I tried switching the
return index(request)
to:
return HttpResponseRedirect("http://127.0.0.1:8000/participants/")
It solves the problem...but I doubt this is the "right" way to do it. What is the correct way to fix this issue?
You can pass just the path to the redirect response:
return HttpResponseRedirect("/participants/")
This way if you change your domain, the redirect will work.
an other solution is to use reverse
from django.core.urlresolvers import reverse
# ...
return HttpResponseRedirect(reverse(index))

Categories