2

I have implemented user login in Django using the following code;

In my urls.py;

.
.
.
    url(r'^login/', UserLogin.as_view(), name='userlogin'),
.
.

In my views.py;

.
.
from django.contrib.auth.forms import AuthenticationForm    
.
.
.
class UserLogin(FormView):
    form_class = AuthenticationForm
    template_name = "auth/login.html"

    def get_success_url(self):
        return reverse('userhome', kwargs={'pk': self.request.user.id})
.
.
.

and my auth/login.html is;

{% block head %}
  <title>Open Radio | Login</title>
{% endblock %}

{% block body %}
  <header>
    <h1>Open Radio</h1>
    <h2>Login Page</h2>
  </header>

  <section>
    {% if form.errors %}
      <p>Your username and password didn't match, please try again.  </p>
    {% endif %}

    <form method="post" action=".">
      {% csrf_token %}
      <p>
        <label for="id_username">Username:</label>
        {{ form.username }}
      </p>
      <p>
        <label for="id_password">Password:</label>
        {{ form.password }}
      </p>
      {% if next %}
        <input type="hidden" name="next" value="{{ next }}" />
      {% endif %}
      <input type="submit" value="login" />
    </form>
  </section>
{% endblock %}

It works and does take me to the user's home page that I have defined.

But when I run the following test;

class TestLoginPage(TestCase):
    .
    .
    .     

    def test_page_logs_in(self):
        """
        Tests if the login page actually logs a user in
        """
        username = "someusername"
        password = "somepassword"
        user = User(username=username,
                    password=password)
        user.save()
        response = self.client.post(reverse("userlogin"),
                                    {"username":username,
                                     "password":password},
                                    follow=True)
        assert response.context["user"].is_authenticated()

I get the following failure;

self = <stationrunner.tests.TestLoginPage testMethod=test_page_logs_in>

    def test_page_logs_in(self):
        """
        Tests if the login page actually logs a user in
        """
        username = "someusername"
        password = "somepassword"
        user = User(username=username,
                    password=password)
        user.save()
        response = self.client.post(reverse("userlogin"),
                                    {"username":username,
                                     "password":password},
                                    follow=True)
>       assert response.context["user"].is_authenticated()
E       AssertionError: assert <bound method   AnonymousUser.is_authenticated of   <django.contrib.auth.models.AnonymousUser object at 0x7f54b5433a50>>()
E        +  where <bound method AnonymousUser.is_authenticated of  <django.contrib.auth.models.AnonymousUser object at 0x7f54b5433a50>> =   <SimpleLazyObject: <django.contrib.auth.models.AnonymousUser object at   0x7f54b5433a50>>.is_authenticated

Could anyone please explain why is this happening

Afzal S.H.
  • 1,084
  • 2
  • 14
  • 27

1 Answers1

4

That login won't succeed because Django expects the password to be a hash but you have saved it in plain text. Do this instead:

user = User.objects.create_user(username=username, password=password)

Edit

Your problem is quite simply that your UserLogin view, despite the name, never actually logs the user in. The AuthenticationForm does what its name implies, ie authenticates, but then does not do anything with that authenticated user to log them in.

At the very least, you would need to call login() somewhere in your view; but there doesn't seem to be a good reason for you to be using your own custom view here rather than the built-in django.contrib.auth.views.login view.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Thanks a lot. The problem is now solved but I have a new one now. `E NoReverseMatch: Reverse for 'userhome' with arguments '()' and keyword arguments '{'pk': None}' not found. 1 pattern(s) tried: ['(?P\\d+)/']` What does this mean ?? Do I need to provide a pk too while creating? That can't/shouldn't be so right!? Or am I missing something else? – Afzal S.H. Apr 09 '15 at 13:05
  • Need more context: that error isn't coming from any of the code you've shown here. Where are you calling `reverse` (or using the `{% url %}` tag) for 'userhome'? This might be better as a new question. – Daniel Roseman Apr 09 '15 at 13:17
  • Its there. Its coming from the UserLogin view's `get_success_url()` method (please see my views.py). The problem is not when I run my project. As said it works fine. Its when I test. .i.e. after I created the object in the manner you just taught me, after doing its works the UserLogin view is unable to move on to its success URL as the created object doesn't have a pk it seems. Hope I am clear. – Afzal S.H. Apr 09 '15 at 13:44
  • `url(r'^(?P\d+)/', UserHome.as_view(), name='userhome'),` This is URL pattern for userhome. – Afzal S.H. Apr 09 '15 at 13:49
  • Thanks a lot Daniel Roseman. The thing is actually I had used the built-in log-in view itself first but due to my original problem I had (the one asked here) I went ahead to use my own view hoping maybe that would sort out the problem for me. Now I am back using the built-in log-in view and with the rectification in my test (thanks to you in both cases) the test passes :). Thanks again :). – Afzal S.H. Apr 09 '15 at 16:18
  • please check out http://stackoverflow.com/questions/30208159/asserting-for-presence-of-added-objects-in-django-manytomany-relation – Afzal S.H. May 13 '15 at 07:21
  • Mr. Roseman could you please see http://stackoverflow.com/questions/30260201/django-typeerror-user-object-is-not-iterable I have got answer to my original query but you can find me having a further trouble in the comments section of the accepted answer, the only one. – Afzal S.H. May 15 '15 at 15:39