0

I've got a simple registration view that takes the user's credentials, creates the user and immediately signs them in. This works perfectly fine on my local development server but when deployed the call to authenticate seems to return None. Annoyingly it doesn't seem to happen every time. Here's my view code:

def register_view( request ):
    import django.contrib.auth as auth
    if request.method == 'POST':
        form = auth.forms.UserCreationForm( request.POST )
        if form.is_valid():
            username = request.POST.get( 'username', None )
            password1 = request.POST.get( 'password1', None )
            auth.models.User.objects.create_user( username=username, password=password1 )
            user = auth.authenticate( username=username, password=password1 )
            if user != None:
                auth.login(request, user)
                return HttpResponseRedirect( request.REQUEST.get( 'next', '/' ) )
            else:
                login_form = auth.forms.AuthenticationForm( data= { 'username': username, 'password': password1 } )
                return render(request, 'login.html', { 'form': login_form } )
        else:
            return render(request, 'register.html', { 'form': form })
    else:
        form = auth.forms.UserCreationForm( error_class=BlogErrorList )
        return render(request, 'register.html', { 'form': form } )

I found this other question that I believe it's the same problem but there was never a verified answer.

I have the same feeling it's a database problem, I am using a High Replication datastore and added 'HIGH_REPLICATION': True to my database settings as decribed here, but that didn't make a difference.

Any ideas what could cause this?

-- EDIT --

I'm using Django-nonrel 1.4 and the standard django.contrib.auth system. The User model is created here and the authentication backend authenticates the user here.

Community
  • 1
  • 1
Yeray Diaz
  • 1,700
  • 14
  • 15

1 Answers1

3

You haven't shown how you the user is defined, and how your auth code is finding the user.

If you are not getting the use by key, or an ancestor query then you will be running into eventual consistency.

You should read this https://developers.google.com/appengine/docs/python/datastore/structuring_for_strong_consistency

Tim Hoffman
  • 12,976
  • 1
  • 17
  • 29
  • Thanks for the link, it makes total sense, however I'm using the default Django-nonrel 1.4 `auth`, please see the updated question. In order to ensure strong consistency would I need to override the model's `create_user`? – Yeray Diaz Jan 12 '14 at 14:41
  • I am not familiar with django, so you will have to look at both create_user and however django fetches the user. I don't know what additional abstractions sit over `user = self.model(username=username, email=email,` in `create_user`. Ancestors don't make sense in this situation, so the only way to get a consistent query, is to either 1. Immediatley after creating the user you use the key to get the entity. This will force the write. Or 2. alternately somehow get django to use the userid as the key, then in the auth code fetch the user by key rather than performing some query. – Tim Hoffman Jan 12 '14 at 15:04
  • That worked! `authenticate` was indeed fetching the user using a query. Passing it the newly created user id and fetching it that way did the trick. Thank you very much! – Yeray Diaz Jan 12 '14 at 18:33