3

I have a problem in registration with django, here is my views code:

def register(request):
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/')
    else:
        form = RegistrationForm()

        args = {'form': form}
        return render(request, 'users/reg_form.html', args)

,but i always get:

ValueError at /user/register/ The view Users.views.register didn't return an HttpResponse object. It returned None instead. Request Method: POST Request URL: http://127.0.0.1:3001/user/register/ Django Version: 2.0.2 Exception Type: ValueError Exception Value: The view Users.views.register didn't return an HttpResponse object. It returned None instead. Exception Location: /home/iah/.local/lib/python3.5/site-packages/django/core/handlers/base.py in _get_response, line 139

Hat hout
  • 471
  • 1
  • 9
  • 18

4 Answers4

3

Check you code and ask yourself what happens if you have a POST request and the form doesn't validate - you'll find out that in this case you have no explicit return path, so the function implicitely returns None.

The fix is dead simple : deindent the last two line of your function, so you when the form doesn't validate you return the rendered template too:

def register(request):
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/')

    else:
        form = RegistrationForm()

    # MAKE SURE WE ALWAYS RETURN A RESPONSE:
    # we end up here when it's a GET request 
    # AND when it's a POST request and the form
    # did not validate   
    args = {'form': form}
    return render(request, 'users/reg_form.html', args)
bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
  • 1
    +1, this is the best approach. When the form is invalid, this answer will redisplay the form with the errors - if you return a `redirect` in the else block then you lose the errors. Also, it is easy to see that this view always returns a response, without having to look at every if/else branch. – Alasdair Mar 27 '18 at 09:48
  • Thanks bruno. I there a way to return an error message "enter a valid data" when redirecting to the same form again? – Hat hout Mar 27 '18 at 10:00
  • i did add a field in the args called errors and pass it with the args to the html,, but it appears with each request to the registration form. i need to make it only if the form is wrong. – Hat hout Mar 27 '18 at 10:01
  • 1
    @Hathout you don't need to add an arg to the template context. You already have the form in the template context, so you can do something like `{% if form.errors %}Please fix the errors below{% endif %}`. – Alasdair Mar 27 '18 at 10:03
  • @Hathout if your form is correctly rendered in the template it should already display errors messages (both fields and non-fields errors). If it doesn't then you'll have to fix your template code (this is documented, and there are quite a few external resources - blog posts, SO questions etc - on the topic). wrt/ adding a generic error message, cf Alasdair's comment. – bruno desthuilliers Mar 27 '18 at 10:26
1

You have to return response from the inner else block:

def register(request):
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('/')
        else:
            # here 
    ...
awesoon
  • 32,469
  • 11
  • 74
  • 99
  • I am using return and render as the answer here: https://stackoverflow.com/questions/26258905/the-view-didnt-return-an-httpresponse-object-it-returned-none-instead ,but nothing changed – Hat hout Mar 27 '18 at 09:37
  • But you do not return anything if your request method is 'POST' but the form is not valid. Use debugger and set your breakpoint to trace your code – awesoon Mar 27 '18 at 09:38
  • i redirected the to / in a new else, but the same error occures – Hat hout Mar 27 '18 at 09:44
  • Are you sure that the code has reloaded? Also please post the updated code – awesoon Mar 27 '18 at 09:45
1

Make sure you return something if the form is not valid and your form.is_valid() fails.

Example:

def register(request):
if request.method == 'POST':
    form = RegistrationForm(request.POST)
    if form.is_valid():
        form.save()
        return redirect('/')
    else:
        return redirect('/') # or render(...)/whatever you need to redirect to
else:
    form = RegistrationForm()

    args = {'form': form}
    return render(request, 'users/reg_form.html', args)

Hope this helps!

N. Ivanov
  • 1,795
  • 2
  • 15
  • 28
0

You are missing the else code. Your if statement says: If the form is valid, save the form. But what if the form is not valid, What if the username is all special characters(ex: !@#$%%%^^) or what if the username is only 1 Character long ex: (username:A). Or what if the password is only 3 characters long (ex: pas) In all these scenarios, the user should get the blank form back. You should also consider using class based views for registration This link will help

def register(request):
    if request.method == 'POST':
        form = RegistrationForm(request.POST)
        **if form.is_valid():** 
 # What if the form is not valid you haven't accounted for that 
            form.save()
            return redirect('/')
    else:       
 # Adding a else solves this problem. The user gets a blank form back                
        form = RegistrationForm()
        args = {'form': form}
        return render(request, 'users/reg_form.html', args)**
Samir Tendulkar
  • 63
  • 1
  • 2
  • 11