I made a custom authentication backend and tried to run it but I found that it doesn't run custom authentication and also returns an error.
Below is the source code.
settings.py
AUTH_USER_MODEL = 'welcome.NDDUser'
AUTHENTICATION_BACKENDS = (
'welcome.backend.MyCustomBackend',
)
welcome/backend.py
from welcome.models import NDDUser
from django.core.exceptions import ValidationError
class MyCustomBackend(object):
# Create an authentication method
# This is called by the standard Django login procedure.
def authenticate(self, username=None, password=None):
try:
# Try to find a user matching your name
user = NDDUser.objects.get(username=username)
except NDDUser.DoesNotExist:
return None
if user.check_password(password):
return user
else:
return None
def get_user(self, user_id):
try:
return NDDUser.objects.get(pk=user_id)
except NDDUser.DoesNotExist:
return None
welcome/views.py
from django.contrib.auth import authenticate, login
from django.shortcuts import render, redirect
from welcome.models import NDDUser, University
from welcome.forms import LoginForm, RegisterForm
def index(request):
if request.method == 'POST':
email = request.POST.get('email')
password = request.POST.get('password')
user = authenticate(email=email, password=password)
if user is not None:
login(request, user)
# Redirect to doctor search page.
return redirect('search:index')
else:
context = { 'login_error_message' : 'You put the wrong information'}
return render(request, 'welcome/index.html', context)
else:
return render(request, 'welcome/index.html')
welcome/forms.py
from django import forms
class LoginForm(forms.Form):
email = forms.CharField()
password = forms.CharField()
class RegisterForm(forms.Form):
university = forms.CharField()
email = forms.CharField()
password1 = forms.CharField(min_length=6)
password2 = forms.CharField(min_length=6)
nickname = forms.CharField(max_length=15, min_length=2)
def clean(self):
cleaned_data = super(RegisterForm, self).clean()
password1 = cleaned_data.get('password1')
password2 = cleaned_data.get('password2')
if password1 and password2:
if password1 != password2:
raise forms.ValidationError("Both passwords r not same.")
return cleaned_data
welcome/models.py
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser
)
from django.core.exceptions import ValidationError
class NDDUserManager(BaseUserManager):
def create_user(self, email, university, password, nickname):
user = self.model(
email=NDDUserManager.normalize_email(email),
university=university,
nickname=nickname,
)
user.set_password(password)
#user.full_clean()
#user.save()
try:
user.full_clean()
except ValidationError as e:
return e
user.save()
return user
class NDDUser(AbstractBaseUser):
university = models.ForeignKey('University')
email = models.EmailField(unique=True, error_messages={'invalid' : 'Invalid mail address','unique' : 'Already registered email address'})
nickname = models.CharField(max_length='15', unique=True, error_messages={'unique' : 'Already registered nickname'})
objects = NDDUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['university', 'password', 'nickname']
class University(models.Model):
name = models.CharField(max_length='20')
email = models.CharField(max_length='20')
def __unicode__(self):
return u'%s %s' % (self.name, self.email)
And I didn't syncdb till writing all the code. Finally, after syncdb and
run it by eclipse (using pydev), I face the error message below:
ERROR 2014-05-09 06:15:49,448 base.py:212] Internal Server Error: /welcome/
Traceback (most recent call last):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/core/handlers/base.py", line 115, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/Users/nextdoordoctor/git/NDDWeb/NDDWeb/src/welcome/views.py", line 19, in index
user = authenticate(email=email, password=password)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/contrib/auth/__init__.py", line 60, in authenticate
user = backend.authenticate(**credentials)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/contrib/auth/backends.py", line 16, in authenticate
user = UserModel._default_manager.get_by_natural_key(username)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/contrib/auth/models.py", line 168, in get_by_natural_key
return self.get(**{self.model.USERNAME_FIELD: username})
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/models/manager.py", line 143, in get
return self.get_query_set().get(*args, **kwargs)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/models/query.py", line 398, in get
num = len(clone)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/models/query.py", line 106, in __len__
self._result_cache = list(self.iterator())
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/models/query.py", line 317, in iterator
for row in compiler.results_iter():
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/models/sql/compiler.py", line 775, in results_iter
for rows in self.execute_sql(MULTI):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/models/sql/compiler.py", line 840, in execute_sql
cursor.execute(sql, params)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/backends/util.py", line 41, in execute
return self.cursor.execute(sql, params)
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/backends/mysql/base.py", line 130, in execute
six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)), sys.exc_info()[2])
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/django-1.5/django/db/backends/mysql/base.py", line 120, in execute
return self.cursor.execute(query, args)
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.6-intel.egg/MySQLdb/cursors.py", line 202, in execute
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/MySQL_python-1.2.4b4-py2.7-macosx-10.6-intel.egg/MySQLdb/connections.py", line 36, in defaulterrorhandler
DatabaseError: (1146, "Table 'nddweb.auth_user' doesn't exist")
INFO 2014-05-09 06:15:49,548 module.py:639] default: "POST /welcome/ HTTP/1.1" 500 12787
------------------------- more information ------------
Finally I put the AUTH_USER_MODEL definition top of the settings.py and syncdb it works! There is no error output like above. But still I have another problem.
When I click submit button of form and post data r send to view.py and authenticate() function doesn't work properly.
Even though I type the correct form data and send it still output that 'You put wrong information'. Django doesn't really import MyCustomBackend I guess..
How can I solve this problem?
Table 'nddweb.auth_user' doesn't existDid you sync the database?