56 votes

Django-AttributeError L'objet 'User' n'a pas d'attribut 'backend' (Mais....it en a un ?)

Afin de connecter les utilisateurs après les avoir enregistrés, j'ai défini manuellement la propriété user.backend. Cela fonctionne normalement dans mes vues. Dans ce cas, j'essaie d'enregistrer l'utilisateur via AJAX. Une AttributeError est générée.

Voici mon code :

 def register_async(request):
    if request.method=='POST':

    userform=MyUserCreationForm(request.POST)
    if userform.is_valid():
        #username of <30 char is required by Django User model.  I'm storing username as a hash of user email 

        user=userform.save(commit=False)
        user.username=hash(user.email)
        user.backend='django.contrib.auth.backends.ModelBackend'
        user.save()

        auth.login(request,user)
        user_status=1
        user_fname=user.first_name
        user_data=[{'user_status':user_status, 'user_fname':user_fname}]
        json_data=json.dumps(user_data)
        response=HttpResponse()
        response['Content-Type']="text/javascript"
        response.write(json_data)
        return response 

    else:
        user_data=[{'user_status':"0"}]
        json_data=json.dumps(user_data)
        response=HttpResponse()
        response['Content-Type']="text/javascript"
        response.write(json_data)
        return response 
else:
    return HttpResponse()

EDIT-- VOICI L'AJAX. IL SEMBLE ASSEZ STANDARD

     //ajax registration.  
$('input#register_submit').click(function(event){
    $(this).attr('disabled','disabled');
    $('<div class="register-animation"><img src="{{site}}media/ajax-loader3.gif"/></div>').appendTo('#register_modal_btn');

    $.post("/register/", $('div#register_side form').serialize(), 
        function(data){
            $.each(data,function(){
            if(this.user_status==1){
                $('.register-animation').remove();
                $('.right_section .top').html('<ul><li class="sep_nav">Hi, '+ this.user_fname + '</li><li class="sep+nav"><a href="http://nabshack.com/logout/">Log Out</a></li><li class="refar_friend"><a href="http://nabshack.com/referral/">Refer a friend and get $50</a></li></ul>');
                $('#post_login_modal').dialog("close");

                $('a.login').unbind('click');
                $('li a.account').unbind('click');

            }       
            else{
            $('input#register_submit').removeAttr('disabled');
            $('.register-animation').remove();
            window.location='{{site}}register';
            }

        });
    },'json');
    return false;
    event.stopPropagation();
});

Ce code exact fonctionne dans les vues non-ajax pour moi. Qu'est-ce que ça donne ?

Merci

0 votes

Pouvez-vous ajouter votre code ajax également ?

0 votes

Utilisez-vous django.contrib.auth for User ? Si oui, alors l'erreur est parfaitement valable, car User ne possède pas cet attribut. Les deux seules façons de l'ajouter à User sont par le biais d'un profil, auquel cas il serait User.get_profile().backend ou par le biais d'une sous-classe, auquel cas il serait CustomUser.backend . Si vous n'utilisez pas django.contrib.auth postez le code de votre User modèle.

0 votes

J'utilise django.contrib.auth. Cependant, votre remarque n'est pas exacte. Voir ce message ( stackoverflow.com/questions/5775268/ ). Vous pouvez directement définir un attr "backend" sur le modèle User. Au-delà de ce fil de discussion, j'ai implémenté cette fonctionnalité avec succès dans d'autres vues. Je pense que c'est l'ajax qui est en jeu ici.

83voto

Luke Sneeringer Points 4032

Vous devez appeler authenticate avant de pouvoir appeler login . authenticate définit un attribut sur l'objet notant quel backend l'a validé avec succès et le libère pour la connexion, ce qui ne se produit pas dans votre code (et c'est l'attribut qui manque).

Documentation : https://docs.djangoproject.com/en/1.8/topics/auth/default/#how-to-log-a-user-in -- Regarde le petit texte qui dit "appel". authenticate() premier".

2 votes

Ce n'est pas vrai, Luke. Je le sais en lisant d'autres fils de discussion ainsi qu'en le testant moi-même. Vous pouvez définir l'attribut backend directement. Consultez l'autre fil de discussion que j'ai laissé dans mes commentaires ci-dessus. Vous pouvez également regarder ailleurs. Définir le backend manuellement est une astuce qui permet d'obtenir le même effet qu'en appelant authenticate.

5 votes

Ok, point concédé. Tu peux te moquer de la effet de la vocation authenticate . Mais vous ne devriez pas le faire, à moins d'avoir une bonne raison, car une future mise à jour pourrait étendre ce que vous avez déjà fait. authenticate fait et ce que Django s'attend à avoir fait.

47voto

jstaab Points 340

Je vais poster ceci comme une réponse, mais je dois https://stackoverflow.com/users/558699/ben dans les commentaires ci-dessus, et https://stackoverflow.com/a/5837046/1467342 . Je parcourais cette question et j'ai manqué que ce que je cherchais se trouvait dans les commentaires. L'ajout d'un backend manuellement a été une solution (bricolée) pour moi deux fois jusqu'à présent :

user.backend = 'django.contrib.auth.backends.ModelBackend'
login(request, user)

Dans les deux cas, je m'appuie sur d'autres méthodes d'authentification (confirmation par courriel et session authentifiée par l'administrateur) pour vérifier l'autorisation de se connecter en tant que cet utilisateur.

7 votes

Bien qu'il soit préférable d'importer les paramètres de django.contrib.conf et d'affecter settings.AUTHENTICATION_BACKENDS au cas où l'utilisation a un backend personnalisé.

0voto

David Lam Points 1176

Dans Django 1.10, django.contrib.auth.login prend maintenant un backend= argument de mot-clé !

https://code.djangoproject.com/ticket/24855

0voto

micfan Points 36

Vous devez appeler authenticate avant d'appeler login même si je ne sais pas pourquoi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X