Unable to get Django HttpResponse - python

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', {})

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})

Newly registered users are not being reflected in the database in 'Django Administration' page after I login as an admin

I am trying to build a user login/signup page using Django. Everything works fine except when I try to register new users by clicking on the register button, the newly registered users are not being reflected in the database in 'Django Administration' page after I login as an admin. Please help.
Here's my code:
urls.py-login
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('accounts.urls'))
]
urls.py-accounts
from django.urls import path
from . import views
urlpatterns = [
path('', views.indexView, name = "home"),
path('dashboard/', views.dashboardView, name = "dashboard"),
# path('login/',),
path('register/',views.registerView, name = "register_url"),
# path('logout,'),
]
views.py
from django.shortcuts import render, redirect
from django.contrib.auth.forms import UserCreationForm
# Create your views here.
def indexView(request):
return render(request, 'index.html')
def dashboardView(request):
return render(request, 'dashboard.html')
def registerView(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return redirect('login_url')
else:
form = UserCreationForm()
return render(request, 'registration/register.html', {'form':form})
index.html
<!DOCTYPE html>
<html>
<head>
<title>Petrol Pump Management System</title>
</head>
<body>
{% block content %}
<h1>User Authentication</h1>
{% endblock %}
</body>
</html>
register.html
{% extends 'index.html'%}
{% block content %}
<h1>Create new account</h1>
<form method = "POST">
{% csrf_token %}
{{form.as_p}}
<button type="submit">Register</button>
</form>
{% endblock %}

Django - No redirect on form submission

I'm at the end of my rope trying to figure out why a simple form redirect is not working. I'm submitting a form with one text field via POST request that gets combined with some data from a function in the same views.py file, which is then saved to the model on the database. For some reason, with the redirect schemes that I've set up on submission of the form, I get either a second copy of the form.
feedbackapp/views.py
from django.shortcuts import render, redirect
from django.http import HttpResponseRedirect
from django.urls import reverse
from .forms import FeedbackForm
from .models import Feedback
def record_feedback(request):
if request.method == 'POST':
form = FeedbackForm(request.POST)
if form.is_valid():
feedback = Feedback()
feedback.submitter_ip = get_client_ip(request)
feedback.feedback_text = form.cleaned_data['feedback']
feedback.save()
return HttpResponseRedirect(reverse('feedbackapp:thanks'))
elif request.method == 'GET':
form = FeedbackForm()
return render(request, 'feedbackapp/feedback_form.html', {'form': form})
def thanks(request):
return render(template_name='feedbackapp/thanks.html',request=request)
# https://stackoverflow.com/questions/4581789/how-do-i-get-user-ip-address-in-django
def get_client_ip(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[-1] # needs to be the last element in array for Heroku
else:
ip = request.META.get('REMOTE_ADDR')
return ip
feedbackapp/forms.py
from django import forms
class FeedbackForm(forms.Form):
feedback = forms.CharField(label='Feedback', max_length=5000)
feedbackapp/templates/feedbackapp/feedback_form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Anonymous Feedback</title>
</head>
<body>
<form action="/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit"/>
</form>
<p><i>Note: IP addresses are collected with each submission.</i></p>
</body>
</html>
feedbackapp/templates/feedbackapp/thanks.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Thanks!</title>
</head>
<body>
<p>Thanks for your feedback.</p>
</body>
</html>
feedbackapp/urls.py
from django.conf.urls import url
from .views import record_feedback, thanks
urlpatterns = [
url('', record_feedback, name='feedback'),
url('thanks/', thanks, name='thanks'),
]
anonfeed/urls.py
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url('', include('feedbackapp.urls'), namespace='feedbackapp'),
]
It is almost as if the thanks view is not associating with the url and the template.
Your empty regex overrides the one for thanks. Change the following line:
url('', record_feedback, name='feedback'),
to
url('^$', record_feedback, name='feedback'),

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