Django View Value Error - django

I'm hitting a wall with this error. I'm sure I'm overlooking something basic, just can't seem to figure it out...
ValueError at /sing/register
The view sing.singer.views.grade didn't return an HttpResponse object.
the view file...
from django.shortcuts import render_to_response
from django import forms
from django.http import HttpResponseRedirect
from django.template import Template, RequestContext
from dash.forms import GradeForm
def register(request):
if request.method == 'POST':
form = GradeForm(data=request.POST)
if form.is_valid():
new_dash_profile = form.save()
new_user = form.save()
return HttpResponseRedirect("/success/")
else:
form = RegisterForm()
return render_to_response('grade.html',{'form':form},context_instance=RequestContext(request) )
my urls.py
urlpatterns = patterns('dashboard.dash.views',
(r'^sing/register','register' ),)
my settings.py
TEMPLATE_DIRS = (
"/home/django/testing/sing/grade/templates",)

def register(request):
if request.method == 'POST':
form = GradeForm(data=request.POST)
if form.is_valid():
new_dash_profile = form.save()
new_user = form.save()
return HttpResponseRedirect("/success/")
else:
form = RegisterForm()
return render_to_response('grade.html',{'form':form},context_instance=RequestContext(request) )
your indents look off?
Initially you are entering the view with request != 'POST' which will never reach that else statement at the bottom, so you dont get a HttpResponse.
The other thing that looks strange is even if you fix your indents, you show the RegisterForm initially, and after the post request, you put the data from your RegisterForm into a GradeForm, if that doesn't validate you show pass your GradeForm to your template. Is this what you intended?
also in your urls.py I would add / to:
(r'^sing/register','register' ),)
like:
(r'^sing/register/','register' ),)
unless you want it to match (for example):
www.site.com/sing/registerasdf/
i might even suggest using '/$' at the end like this:
(r'^sing/register/$','register' ),)
to prevent matches to (for example):
www.site.com/sing/register/asdf/asdf/asdf/
www.site.com/sing/register/asdf/asdf/
www.site.com/sing/register/asdf/

Judging from the code, the only time it does not return a HttpResponse is when it's not a POST request. Maybe you are doing a GET instead?

I think its your HttpResonseRedirect. I can't say I've used it that often (if at all). If I were you I would try shortcut redirect
http://docs.djangoproject.com/en/dev/topics/http/shortcuts/#redirect

Related

The view formApp.views.formRegister didn't return an HttpResponse object

Views.py
from django.shortcuts import render
from . models import Registerform
# Create your views here.
def formRegister(request):
if request.method == 'POST':
if request.POST.get('firstN') and request.POST.get('lastN') and request.POST.get('Email') and request.POST.get('pass'):
Registerform = Post()
Registerform.firstName = request.POST.get('firstN')
Registerform.lastName = request.POST.get('lastN')
Registerform.email = request.POST.get('Email')
Registerform.password = request.POST.get('pass')
Registerform.save()
return render(request, 'formApp/formreg.html', context_instance=RequestContext(request))
As you can see in the above error image, my code is not functioning properly. I have added my models.py and views.py code. Please help me to resolve the issue.
Why it doesn't work
Every django view, has to return a valid HttpResponse object (as the error message says). That is this part of your code:
return render(request, 'formApp/formreg.html', context_instance=RequestContext(request))
The render function is a shortcut which will return such an object.
The problem though is that, all of this is wrapped inside an if request.method == 'POST':, and so if the request is something that is not a POST, the function just returns nothing. Hence the error
How to fix it
As you can see in the screen shot you've provided, the request method is a GET, so you need to add some code to deal with the case of a GET request.
Add something like this:
if request.method == "GET":
return render(...) # put what you want here

django redirect after form submission not working

new to django
so this one probably has a very simple answer but i cannot for the life of me find the specific solution to this. I am simply trying to redirect to a new URL after a form submission with a FileField.
I can navigate to the URL separately and it works fine.
The file uploads correctly so I know it is validated correctly.
But the redirect returns the following error:
Reverse for 'success' not found. 'success' is not a valid view function or pattern name.
I have tried a bunch of different naming conventions, but none has worked. It looks to me like I have setup the URL and passed it correctly.
Would really appreciate some help with this. The simplest problems are the most frustrating!
Here are the views.
from django.shortcuts import render, redirect
from django.http import HttpResponse, HttpResponseRedirect
from django.urls import reverse
from .forms import InvestmentReportForm
def upload(request):
if request.method == 'POST':
form = InvestmentReportForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('success')
else:
form = InvestmentReportForm()
return render(request, 'app/upload.html', {'form': form})
def success(request):
return HttpResponse("File successfully uploaded")
And my urls.py:
app_name = 'app'
urlpatterns = [
path('', views.index, name='index'),
path('upload/', views.upload, name='upload'),
path('success/', views.success, name='success'),
path('performance/', views.performance, name='performance'),
]
The answer was simple as I suspected. For others, if you use a namespace for a set of url patterns, you have to refer to that namespace when calling those urls. For this example:
return redirect('app:success')
def upload(request):
if request.method == 'POST':
form = InvestmentReportForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('success/')
else:
form = InvestmentReportForm()
return render(request, 'app/upload.html', {'form': form})

Django 1.6 - reusable view with redirect

I have just made reusable comments app that can be attached to any model, please see view I have problem with ( I didn't include whole logic, only the one relevant to the question).
When there is no request.POST, all is working fine, however when I try to add the comment, after it is saved there is some problem with redirect, I am getting error
dictionary update sequence element #0 has length 0; 2 is required
problematic line is context.update(dictionary). It looks like it is empty when comment is added, but I don't understand why.
My logic is this:
when there is no request.POST, view add_comment will return
{'comment_form': comment_form, 'comments': comments}
when request.method==POST' , context.update(dictionary) shouldn't
be even executed, because of return redirect(node). It should result
in starting code executing in view profile, because that's where
redirect(node) should lead to.
I know I could just use redirect in profile.views.py, but then I will need to do this for every view with added comments, which is extremely unconvenient.
comment.views.py
from django.shortcuts import redirect
from comment.forms import AddCommentForm
from comment.models import Comment
def add_comment(request, node):
if request.user.is_authenticated():
user = request.user
else:
user = None
comment_form = None
comments = Comment.objects.get_comments(node) # custom manager method for getting all comments
if user:
if request.method == 'POST':
comment_form = AddCommentForm(request.POST)
if comment_form.is_valid():
comment_form.save(node=node, user=user) # custom form save method, updating missing fields
return redirect(node) #redirect to node.get_absolute_url()
else:
comment_form = AddCommentForm()
return {'comment_form': comment_form, 'comments': comments}
profile.views.py - another app, I want to reduce the code for adding comment by only referring to view add_comment
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.models import User
from comment.views import add_comment
def profile(request, id):
user = get_object_or_404(User, id=id)
dictionary = add_comment(request, user)
context = {'user': user}
context.update(dictionary) #problematic line
return render(request, 'profile/profile account.html', context)
The problem is that add_comment can return something that isn't a dictionary: that is, a redirect (which is a subclass of HttpResponse). You could always check the type of what is returned before using it:
result = add_comment(request, user)
if not isinstance(result, dict):
return result
else:
context.update(result)

Passing values from views.py to a template

Maybe this is a very silly question, but I'm new to django.
My application doesn't require the use of any database, so my models.py is empty.My application receives a POST request from a template which is handled in my views.py and the response is another template.How can I pass values from views.py to my new template (Without using the database)?
My views.py
from django.shortcuts import render_to_response
from django.template import RequestContext
def search_isbn(request):
if request.method == 'POST':
x=500
return render_to_response('results.html',RequestContext(request))
I wish to pass the value x to results.html.How can I do that ?
Any help would be appreciated. Thanks in Advance.
Pass a dictionary that contains the variables you want to pass.
def search_isbn(request):
x = 0 # Without this, you will get NameError if request.method is not 'POST'
if request.method == 'POST':
x = 500
return render_to_response('results.html', RequestContext(request, {'x': x}))
# ^^^^^^^^
Also you can use render function.
from django.shortcuts import render
def search_isbn(request):
x = 0
if request.method == 'POST':
x=500
return render('results.html', {'x':x})

Redirect / return to same (previous) page in Django?

What are the options when you want to return the user to the same page in Django and what are the pros/cons of each?
Methods I know:
HTTP_REFERER
GET parameter containing the previous URL
Session data to store the previous URL
Are there any other?
One of the way is using HTTP_REFERER header like as below:
from django.http import HttpResponseRedirect
def someview(request):
...
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
Not sure of cons of this!
100% working Example
For Class Based View and Function:
from django.http import HttpResponseRedirect
...
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
or
from django.http import HttpResponseRedirect
...
return HttpResponseRedirect(self.request.META.get('HTTP_REFERER'))
Example -
class TaskNotificationReadAllView(generic.View):
def get(self, request, *args, **kwargs):
TaskNotification.objects.filter(assigned_to=request.user).update(read=True)
print(request.META.get('HTTP_REFERER'))
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
While the question and answer is old, I think it's lacking a few options. I have not find any cons with the methods, I would be happy to know if there are any?
request.path_info
request.get_full_path()
request.build_absolute_uri()
from django.shortcuts import redirect
redirect(request.path_info) # No query parameters
redirect(request.build_absolute_uri()) # Keeps query parameters
redirect(request.get_full_path()) # Keeps query parameters
In django view suppose you are not logged in but click on some content that content trigger some url like /board/2/new_topic then #login_required will redirect you to login page with this url
http://localhost:8000/signin/?next=/boards/2/new_topic/
so our aim is redirect to http://localhost:8000/boards/2/new_topic/ page after successful login so one line we will have to add
if 'next' in request.GET:
return redirect(request.GET['next'])
then if it next is there then it will redirect according to that other normal redirect .
Views.py :
def signin(request):
if request.method == "POST":
user_login_form = UserLoginForm(request.POST)
email = request.POST['email']
password = request.POST['password']
user = authenticate(request, email=email, password=password)
if user and user.is_active:
login(request, user)
if 'next' in request.GET:
return redirect(request.GET['next'])
else:
return redirect('home')
else:
return render(request, 'signin.html', context={'form': user_login_form})
else:
user_login_form = UserLoginForm()
return render(request, 'signin.html', context={'form': user_login_form})