Django "login() takes exactly 1 argument (2 given)" error

Django

Django Problem Overview


I'm trying to store the user's ID in the session using django.contrib.auth.login . But it is not working not as expected.

I'm getting error login() takes exactly 1 argument (2 given)

With login(user) I'm getting AttributeError at /login/ User' object has no attribute 'method'

I'm using slightly modifyed example form http://docs.djangoproject.com/en/dev/topics/auth/ :

from django.shortcuts import render_to_response
from django.contrib.auth import authenticate, login

def login(request):
    msg = []
    if request.method == 'POST':
        username = request.POST['u']
        password = request.POST['p']
        user = authenticate(username=username, password=password)
        if user is not None:
            if user.is_active:
                login(request, user)
                msg.append("login successful")
            else:
                msg.append("disabled account")
        else:
            msg.append("invalid login")
    return render_to_response('login.html', {'errors': msg})

there's nothing special about login.html:

<html>
<head>
    <title></title>
</head>
<body>
    <form action="/login/" method="post">
        Login:&nbsp; <input type="text" name="u">
    <br/>
        Password:&nbsp; <input type="password" name="p">
        <input type="submit" value="Login">
    </form>
    {% if errors %}
        <ul>
            {% for error in errors %}
            <li>{{ error }}</li>
            {% endfor %}
        </ul>
    {% endif %}

</body>
</html>

Does anybody have idea how to make login() work.

Django Solutions


Solution 1 - Django

Your view function is also called login, and the call to login(request, user) ends up being interpreted as a attempt to call this function recursively:

def login(request):
    ...
    login(request, user)

To avoid it rename your view function or refer to the login from django.contrib.auth in some different way. You could for example change the import to rename the login function:

from django.contrib.auth import login as auth_login

...
auth_login(request, user)

Solution 2 - Django

One possible fix:

from django.contrib import auth

def login(request):
    # ....
    auth.login(request, user)
    # ...

Now your view name doesn't overwrite django's view name.

Solution 3 - Django

Another way:

from django.contrib.auth import login as auth_login

then call auth_login(request, user) instead of login(request, user).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlex BolotovView Question on Stackoverflow
Solution 1 - DjangosthView Answer on Stackoverflow
Solution 2 - DjangoarsView Answer on Stackoverflow
Solution 3 - DjangobbsimonView Answer on Stackoverflow