0

I am using django 1.7 python 3.4 I have created a custom MyUser class which is derived from AbstractBaseUser. Now, when I try to register a user, I am getting the error 'AnonymousUser' object has no attribute 'backend'. views.py

def signup(request):
    if request.method == 'POST':
        form = SignupForm(request.POST)
        if not form.is_valid():
            return "form invalid"  # render(request, 'auth/signup.html', {'form': form})
        else:

            email = form.cleaned_data.get('email')
            enterprise = form.cleaned_data.get('enterprise')
            first_name = form.cleaned_data.get('first_name')
            last_name = form.cleaned_data.get('last_name')
            password = form.cleaned_data.get('password')
            MyUser.objects.create_myuser(email=email, enterprise=enterprise, first_name=first_name, last_name=last_name,
                                         password=password,)
            myuser = authenticate(email=email, password=password)
            # myuser.backend = 'django.contrib.auth.backends.ModelBackend'
            # authenticate(email=email, password=password)
            login(request, myuser)
            welcome_post = u'{0}from {1} has joined the network.'.format(myuser.first_name, myuser.enterprise)
            node = Node(myuser=myuser, post=welcome_post)
            node.save()
            return redirect('/')
    else:
        return render(request, 'accounts/signup.html', {'form': SignupForm()})

Also, the user is not getting saved into database.

Traceback:
File "C:\Python34\lib\site-packages\django\core\handlers\base.py" in get_response
  111.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\sp\ilog_dev\accounts\views.py" in signup
  27.             login(request, myuser)
File "C:\Python34\lib\site-packages\django\contrib\auth\__init__.py" in login
  98.     request.session[BACKEND_SESSION_KEY] = user.backend
File "C:\Python34\lib\site-packages\django\utils\functional.py" in inner
  225.         return func(self._wrapped, *args)

Exception Type: AttributeError at /accounts/signup/
Exception Value: 'AnonymousUser' object has no attribute 'backend'

models.py

class MyUserManager(BaseUserManager):
    def create_myuser(self, email, first_name, last_name, enterprise, password=None):
        if not email:
            raise ValueError('Users must have an email address')
        if not first_name:
            raise ValueError("must have a first_name")
        if enterprise not in Enterprise.objects.all():
            raise ValueError("please specify a valid enterprise or register a new one")

        myuser = self.model(email=self.normalize_email(email), first_name=first_name,
                            last_name=last_name, enterprise=enterprise,)

        myuser.set_password(password)
        myuser.save()  # using=self._db
        print("user saved")

        return myuser
sprksh
  • 2,204
  • 2
  • 26
  • 43
  • P.S. the problem is not due to "set_password" thing. – sprksh Mar 05 '15 at 10:34
  • 1
    I suspect `authenticate` fails and returns `None`, in which case `login` will fall back to `request.user` which is an `AnonymousUser` without a `backend` attribute. – knbk Mar 05 '15 at 10:35
  • Also the user is not getting saved to the database. So evenif it tries to authenticate, what will it authenticate.? P.S: I am new to django and web development – sprksh Mar 05 '15 at 10:42
  • `MyUser.objects.create_myuser` can you post the code in this method? – knbk Mar 05 '15 at 10:59
  • @knbk yup posted it,please have a look, – sprksh Mar 05 '15 at 11:03
  • Do you have an appropriate authentication backend installed that accepts an email and password? – knbk Mar 05 '15 at 11:09
  • Ok, the MyUser class inherits from AbstractBaseUser class. Also I have explicitly defined USERNAME_FIELD = "email" In that case do i need any other authentication backend – sprksh Mar 05 '15 at 11:17
  • The docs aren't too clear, but you must check that `authenticate` does not return `None` before you try to login the user. That doesn't explain why `authenticate` fails in the first place, though. Do you have `get_by_natural_key` defined on your user manager? – knbk Mar 05 '15 at 11:59
  • no, i havent defined it. but i think the problem is due to user not getting saved. I tried commenting out myuser.save() still it is showing the same error. that means that the user is not getting saved anyway so how can it be authenticated – sprksh Mar 05 '15 at 12:17
  • Not necessarily, the behaviour will be the same if authentication fails for another reason. Can you check that the user exists in the database? Nvm about `get_by_natural_key`, that's defined by the `BaseUserManager`. Can you post your full `MyUser` model? – knbk Mar 05 '15 at 12:36
  • Right now I have got something, the save method was overriding the save method at base.py and was actually not saving the user actually. let me correct that and if even then it doesn't work, I will get back to you.. – sprksh Mar 05 '15 at 12:51

2 Answers2

1

The problem is quite simple. The User is not being saved into the database. As you say, there must be some problem with the save method in your user model. Also, the save method has no bug that stops it but it is working fine as a piece of code except saving the object

So what happens is when you signup as a user, everything runs fine, but the user is not saved. After that it tries to call back the user and it returns anonymous user. Now when you call any attribute of the user, it will raise a similar error.

Check your save method.

Rohit
  • 475
  • 1
  • 7
  • 16
0

The issue here is that you migrated the auth models to the database then migrated your custom user as a second step.

You need to start with a clean database and migrate your custom user in the first migration command you issue to the database.

There is mention in the documentation that you should always create your custom user tables as the first step, otherwise django will get itself in a twist.

Warning

Changing AUTH_USER_MODEL has a big effect on your database structure. It changes the tables that are available, and it will affect the construction of foreign keys and many-to-many relationships. If you intend to set AUTH_USER_MODEL, you should set it before creating any migrations or running manage.py migrate for the first time.

Changing this setting after you have tables created is not supported by makemigrations and will result in you having to manually fix your schema, port your data from the old user table, and possibly manually reapply some migrations.

ajaali
  • 860
  • 12
  • 16