简体   繁体   中英

MultiValueDictKeyError in Django Login and Registration project

I'm working on a Login and Registration page, but keep hitting this error:

MultiValueDictKeyError at /pokesregister/
"'name'"

Below is my views.py code (along with lines commented out form various things I've tried based on google searching):

    from django.shortcuts import render, HttpResponse, redirect
from .models import User
from django.core.urlresolvers import reverse



def index(request):

    return render(request, 'poke/index.html')

def login(request):
    print '*'*75
    if request.method == 'POST':
        user_tuple = User.userManager.login(request.POST['email'], request.POST['password'])

        if user_tuple[0]: # true or false from the returned tuple
            request.session['id'] = user_tuple[1].id
            request.session['name'] = user_tuple[1].name + " " + user_tuple[1].alias        

            return render(request, 'poke/pokes.html')

        else:
            return render(request,'poke/pokes.html', user_tuple[1])
    return HttpResponse('login')

def register(request):
    print '*'*75
    print request.POST['name']
    user_tuple = User.userManager.register(request.POST['name'], request.POST['alias'], request.POST['email'], request.POST['password'], request.POST['confirm_password'], request.POST['dob'])
    # name = request.POST.get('name')
    # user_tuple = User.userManager.register(request.GET.get('name', False), request.GET.get('alias', False), request.GET.get('email', False), request.GET.get('password', False), request.GET.get('confirm_password', False), request.GET.get('dob', False))

    if user_tuple[0]:
        return render(request, 'poke/pokes.html', user_tuple[1])

    else:
        return render(request, 'poke/index.html', user_tuple[1])

And below is my models.py:

from __future__ import unicode_literals
import bcrypt
from django.db import models
import re
EMAIL_REGEX = re.compile(r'^[a-zA-Z0-9.+_-]+@[a-zA-Z0-9._-]+.[a-zA-Z]*$')

class UserManager(models.Manager):
    def login(self, email, password):
        try:
            user = self.get(email__iexact=email) # case insensitive comparison
            user2 = self.filter(email__iexact=email)
            print user
            print user2
            print user.password
            if user and bcrypt.hashpw(password.encode('utf-8'),user.password.encode('utf-8')) == user.password.encode('utf-8'):
                return (True, user)
                # should be classified as a successful login event

            return(False,{"login": "login failed"})
        except:
            print "Failed"
            return(False,{"login": "login failed"})

    def register(self, name, alias, email, password, confirm_password, dob):
        errors = {}

        if len(name) < 2:
            errors['name'] = "Name is too short"
        if len(alias) < 2:
            errors['alias'] = "Alias is too short"
        if len(password) < 8:
            errors['password'] = "Password is too short"
        if password != confirm_password:
            errors['confirm_password'] = "Passwords must match"
        try:
            if user == self.get(email__iexact=email):
                errors['invalid'] = "Invalid registration"
        except:
            pass
        if not EMAIL_REGEX.match(email):
            errors['email'] = "Please enter a valid email"

        if dob:
            pass

        if errors:
            return (False, errors)
        else:

        # register this person!
            password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
            user = self.create(name=name, alias=alias, password=password, email=email, dob=dob)
            user.save()
            print(User.objects.all())
            return (True, {"Success":"success"})

class User(models.Model):

    name = models.CharField(max_length=45)
    alias = models.CharField(max_length=45)
    email = models.EmailField() # auto validation for us!
    password = models.CharField(max_length=255)
    pokes = models.IntegerField(default=0)
    dob = models.DateField(auto_now=False, auto_now_add=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    userManager = UserManager()
    objects = models.Manager()


class Pokers(models.Model):
    user1 = models.ForeignKey(User, related_name="f1")
    user2 = models.ForeignKey(User, related_name="f2")
    created_at = models.DateField(auto_now_add=True)
    updated_at = models.DateField(auto_now=True)

Lastly, here's my urls.py file:

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.index, name = 'index'),
    url(r'^register/$', views.register, name = 'register'),
    url(r'^login/$', views.login, name = 'login'),
]

If anyone has any idea what could be going on here, I would really appreciate some advice. I've used this line previously, and made it work, but I'm not entirely sure how:

user_tuple = User.userManager.register(request.POST['name'],
request.POST['alias'], request.POST['email'],
request.POST['password'], request.POST['confirm_password'],
request.POST['dob'])

I apologize for any obvious errors, as I'm fairly new to all of this (obviously).

Thanks!

You are getting the error because the key you are trying to fetch ('name') is not there. If there is a situation where the user requests the register view without having the 'name' key, then it will throw an error.

Instead of:

request.POST['name']

Do:

request.POST.get('name', False);

If name doesn't exist, instead of throwing an error, the method returns False.

I would also recommend checking it is POST or GET similar to how you did in your login view. (if request.method == 'POST')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM