Skip to content

Commit

Permalink
Fixed #2332 -- Introduced is_authenticated() method on User and Anony…
Browse files Browse the repository at this point in the history
…mousUser classes. Recommended its use over is_anonymous in the docs. Changed internal Django use to match this recommendation. Thanks to SmileyChris and Gary Wilson for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@3360 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
malcolmt committed Jul 19, 2006
1 parent 533594d commit 51705f6
Show file tree
Hide file tree
Showing 12 changed files with 46 additions and 33 deletions.
4 changes: 2 additions & 2 deletions django/contrib/admin/templates/admin/base.html
Expand Up @@ -20,9 +20,9 @@
<div id="branding"> <div id="branding">
{% block branding %}{% endblock %} {% block branding %}{% endblock %}
</div> </div>
{% if not user.is_anonymous %}{% if user.is_staff %} {% if user.is_authenticated and user.is_staff %}
<div id="user-tools">{% trans 'Welcome,' %} <strong>{% if user.first_name %}{{ user.first_name|escape }}{% else %}{{ user.username }}{% endif %}</strong>. {% block userlinks %}<a href="doc/">{% trans 'Documentation' %}</a> / <a href="password_change/">{% trans 'Change password' %}</a> / <a href="logout/">{% trans 'Log out' %}</a>{% endblock %}</div> <div id="user-tools">{% trans 'Welcome,' %} <strong>{% if user.first_name %}{{ user.first_name|escape }}{% else %}{{ user.username }}{% endif %}</strong>. {% block userlinks %}<a href="doc/">{% trans 'Documentation' %}</a> / <a href="password_change/">{% trans 'Change password' %}</a> / <a href="logout/">{% trans 'Log out' %}</a>{% endblock %}</div>
{% endif %}{% endif %} {% endif %}
{% block nav-global %}{% endblock %} {% block nav-global %}{% endblock %}
</div> </div>
<!-- END Header --> <!-- END Header -->
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/admin/views/decorators.py
Expand Up @@ -46,7 +46,7 @@ def staff_member_required(view_func):
member, displaying the login page if necessary. member, displaying the login page if necessary.
""" """
def _checklogin(request, *args, **kwargs): def _checklogin(request, *args, **kwargs):
if not request.user.is_anonymous() and request.user.is_staff: if request.user.is_authenticated() and request.user.is_staff:
# The user is valid. Continue to the admin page. # The user is valid. Continue to the admin page.
if request.POST.has_key('post_data'): if request.POST.has_key('post_data'):
# User must have re-authenticated through a different window # User must have re-authenticated through a different window
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/auth/decorators.py
Expand Up @@ -17,7 +17,7 @@ def _checklogin(request, *args, **kwargs):
return _checklogin return _checklogin
return _dec return _dec


login_required = user_passes_test(lambda u: not u.is_anonymous()) login_required = user_passes_test(lambda u: u.is_authenticated())
login_required.__doc__ = ( login_required.__doc__ = (
""" """
Decorator for views that checks that the user is logged in, redirecting Decorator for views that checks that the user is logged in, redirecting
Expand Down
8 changes: 8 additions & 0 deletions django/contrib/auth/models.py
Expand Up @@ -125,6 +125,11 @@ def get_absolute_url(self):
def is_anonymous(self): def is_anonymous(self):
"Always returns False. This is a way of comparing User objects to anonymous users." "Always returns False. This is a way of comparing User objects to anonymous users."
return False return False

def is_authenticated(self):
"""Always return True. This is a way to tell if the user has been authenticated in templates.
"""
return True


def get_full_name(self): def get_full_name(self):
"Returns the first_name plus the last_name, with a space in between." "Returns the first_name plus the last_name, with a space in between."
Expand Down Expand Up @@ -293,3 +298,6 @@ def get_and_delete_messages(self):


def is_anonymous(self): def is_anonymous(self):
return True return True

def is_authenticated(self):
return False
6 changes: 3 additions & 3 deletions django/contrib/comments/templates/comments/form.html
Expand Up @@ -2,10 +2,10 @@
{% if display_form %} {% if display_form %}
<form {% if photos_optional or photos_required %}enctype="multipart/form-data" {% endif %}action="/comments/post/" method="post"> <form {% if photos_optional or photos_required %}enctype="multipart/form-data" {% endif %}action="/comments/post/" method="post">


{% if user.is_anonymous %} {% if user.is_authenticated %}
<p><label for="id_username">{% trans "Username:" %}</label> <input type="text" name="username" id="id_username" /><br />{% trans "Password:" %} <input type="password" name="password" id="id_password" /> (<a href="/accounts/password_reset/">{% trans "Forgotten your password?" %}</a>)</p>
{% else %}
<p>{% trans "Username:" %} <strong>{{ user.username }}</strong> (<a href="/accounts/logout/">{% trans "Log out" %}</a>)</p> <p>{% trans "Username:" %} <strong>{{ user.username }}</strong> (<a href="/accounts/logout/">{% trans "Log out" %}</a>)</p>
{% else %}
<p><label for="id_username">{% trans "Username:" %}</label> <input type="text" name="username" id="id_username" /><br />{% trans "Password:" %} <input type="password" name="password" id="id_password" /> (<a href="/accounts/password_reset/">{% trans "Forgotten your password?" %}</a>)</p>
{% endif %} {% endif %}


{% if ratings_optional or ratings_required %} {% if ratings_optional or ratings_required %}
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/comments/templatetags/comments.py
Expand Up @@ -114,7 +114,7 @@ def render(self, context):
comment_list = get_list_function(**kwargs).order_by(self.ordering + 'submit_date').select_related() comment_list = get_list_function(**kwargs).order_by(self.ordering + 'submit_date').select_related()


if not self.free: if not self.free:
if context.has_key('user') and not context['user'].is_anonymous(): if context.has_key('user') and context['user'].is_authenticated():
user_id = context['user'].id user_id = context['user'].id
context['user_can_moderate_comments'] = Comment.objects.user_is_moderator(context['user']) context['user_can_moderate_comments'] = Comment.objects.user_is_moderator(context['user'])
else: else:
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/comments/views/comments.py
Expand Up @@ -63,7 +63,7 @@ def get_validator_list(rating_num):
validator_list=get_validator_list(8), validator_list=get_validator_list(8),
), ),
]) ])
if not user.is_anonymous(): if user.is_authenticated():
self["username"].is_required = False self["username"].is_required = False
self["username"].validator_list = [] self["username"].validator_list = []
self["password"].is_required = False self["password"].is_required = False
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/comments/views/karma.py
Expand Up @@ -15,7 +15,7 @@ def vote(request, comment_id, vote):
rating = {'up': 1, 'down': -1}.get(vote, False) rating = {'up': 1, 'down': -1}.get(vote, False)
if not rating: if not rating:
raise Http404, "Invalid vote" raise Http404, "Invalid vote"
if request.user.is_anonymous(): if not request.user.is_authenticated():
raise Http404, _("Anonymous users cannot vote") raise Http404, _("Anonymous users cannot vote")
try: try:
comment = Comment.objects.get(pk=comment_id) comment = Comment.objects.get(pk=comment_id)
Expand Down
2 changes: 1 addition & 1 deletion django/contrib/flatpages/views.py
Expand Up @@ -22,7 +22,7 @@ def flatpage(request, url):
f = get_object_or_404(FlatPage, url__exact=url, sites__id__exact=settings.SITE_ID) f = get_object_or_404(FlatPage, url__exact=url, sites__id__exact=settings.SITE_ID)
# If registration is required for accessing this page, and the user isn't # If registration is required for accessing this page, and the user isn't
# logged in, redirect to the login page. # logged in, redirect to the login page.
if f.registration_required and request.user.is_anonymous(): if f.registration_required and not request.user.is_authenticated():
from django.contrib.auth.views import redirect_to_login from django.contrib.auth.views import redirect_to_login
return redirect_to_login(request.path) return redirect_to_login(request.path)
if f.template_name: if f.template_name:
Expand Down
12 changes: 6 additions & 6 deletions django/views/generic/create_update.py
Expand Up @@ -20,7 +20,7 @@ def create_object(request, model, template_name=None,
the form wrapper for the object the form wrapper for the object
""" """
if extra_context is None: extra_context = {} if extra_context is None: extra_context = {}
if login_required and request.user.is_anonymous(): if login_required and not request.user.is_authenticated():
return redirect_to_login(request.path) return redirect_to_login(request.path)


manipulator = model.AddManipulator(follow=follow) manipulator = model.AddManipulator(follow=follow)
Expand All @@ -39,7 +39,7 @@ def create_object(request, model, template_name=None,
# No errors -- this means we can save the data! # No errors -- this means we can save the data!
new_object = manipulator.save(new_data) new_object = manipulator.save(new_data)


if not request.user.is_anonymous(): if request.user.is_authenticated():
request.user.message_set.create(message="The %s was created successfully." % model._meta.verbose_name) request.user.message_set.create(message="The %s was created successfully." % model._meta.verbose_name)


# Redirect to the new object: first by trying post_save_redirect, # Redirect to the new object: first by trying post_save_redirect,
Expand Down Expand Up @@ -86,7 +86,7 @@ def update_object(request, model, object_id=None, slug=None,
the original object being edited the original object being edited
""" """
if extra_context is None: extra_context = {} if extra_context is None: extra_context = {}
if login_required and request.user.is_anonymous(): if login_required and not request.user.is_authenticated():
return redirect_to_login(request.path) return redirect_to_login(request.path)


# Look up the object to be edited # Look up the object to be edited
Expand All @@ -113,7 +113,7 @@ def update_object(request, model, object_id=None, slug=None,
if not errors: if not errors:
object = manipulator.save(new_data) object = manipulator.save(new_data)


if not request.user.is_anonymous(): if request.user.is_authenticated():
request.user.message_set.create(message="The %s was updated successfully." % model._meta.verbose_name) request.user.message_set.create(message="The %s was updated successfully." % model._meta.verbose_name)


# Do a post-after-redirect so that reload works, etc. # Do a post-after-redirect so that reload works, etc.
Expand Down Expand Up @@ -162,7 +162,7 @@ def delete_object(request, model, post_delete_redirect,
the original object being deleted the original object being deleted
""" """
if extra_context is None: extra_context = {} if extra_context is None: extra_context = {}
if login_required and request.user.is_anonymous(): if login_required and not request.user.is_authenticated():
return redirect_to_login(request.path) return redirect_to_login(request.path)


# Look up the object to be edited # Look up the object to be edited
Expand All @@ -180,7 +180,7 @@ def delete_object(request, model, post_delete_redirect,


if request.method == 'POST': if request.method == 'POST':
object.delete() object.delete()
if not request.user.is_anonymous(): if request.user.is_authenticated():
request.user.message_set.create(message="The %s was deleted." % model._meta.verbose_name) request.user.message_set.create(message="The %s was deleted." % model._meta.verbose_name)
return HttpResponseRedirect(post_delete_redirect) return HttpResponseRedirect(post_delete_redirect)
else: else:
Expand Down
29 changes: 17 additions & 12 deletions docs/authentication.txt
Expand Up @@ -95,7 +95,11 @@ In addition to those automatic API methods, ``User`` objects have the following
custom methods: custom methods:


* ``is_anonymous()`` -- Always returns ``False``. This is a way of * ``is_anonymous()`` -- Always returns ``False``. This is a way of
comparing ``User`` objects to anonymous users. differentiating ``User`` and ``AnonymousUser`` objects. Generally, you
should prefer using ``is_authenticated()`` to this method.

* ``is_authenticated()`` -- Always returns ``True``. This is a way to
tell if the user has been authenticated.


* ``get_full_name()`` -- Returns the ``first_name`` plus the ``last_name``, * ``get_full_name()`` -- Returns the ``first_name`` plus the ``last_name``,
with a space in between. with a space in between.
Expand Down Expand Up @@ -219,6 +223,7 @@ the ``django.contrib.auth.models.User`` interface, with these differences:


* ``id`` is always ``None``. * ``id`` is always ``None``.
* ``is_anonymous()`` returns ``True`` instead of ``False``. * ``is_anonymous()`` returns ``True`` instead of ``False``.
* ``is_authenticated()`` returns ``False`` instead of ``True``.
* ``has_perm()`` always returns ``False``. * ``has_perm()`` always returns ``False``.
* ``set_password()``, ``check_password()``, ``save()``, ``delete()``, * ``set_password()``, ``check_password()``, ``save()``, ``delete()``,
``set_groups()`` and ``set_permissions()`` raise ``NotImplementedError``. ``set_groups()`` and ``set_permissions()`` raise ``NotImplementedError``.
Expand Down Expand Up @@ -254,12 +259,12 @@ Once you have those middlewares installed, you'll be able to access
``request.user`` in views. ``request.user`` will give you a ``User`` object ``request.user`` in views. ``request.user`` will give you a ``User`` object
representing the currently logged-in user. If a user isn't currently logged in, representing the currently logged-in user. If a user isn't currently logged in,
``request.user`` will be set to an instance of ``AnonymousUser`` (see the ``request.user`` will be set to an instance of ``AnonymousUser`` (see the
previous section). You can tell them apart with ``is_anonymous()``, like so:: previous section). You can tell them apart with ``is_authenticated()``, like so::


if request.user.is_anonymous(): if request.user.is_authenticated():
# Do something for anonymous users. # Do something for authenticated users.
else: else:
# Do something for logged-in users. # Do something for anonymous users.


.. _request objects: http://www.djangoproject.com/documentation/request_response/#httprequest-objects .. _request objects: http://www.djangoproject.com/documentation/request_response/#httprequest-objects
.. _session documentation: http://www.djangoproject.com/documentation/sessions/ .. _session documentation: http://www.djangoproject.com/documentation/sessions/
Expand Down Expand Up @@ -323,19 +328,19 @@ The raw way
~~~~~~~~~~~ ~~~~~~~~~~~


The simple, raw way to limit access to pages is to check The simple, raw way to limit access to pages is to check
``request.user.is_anonymous()`` and either redirect to a login page:: ``request.user.is_authenticated()`` and either redirect to a login page::


from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect


def my_view(request): def my_view(request):
if request.user.is_anonymous(): if not request.user.is_authenticated():
return HttpResponseRedirect('/login/?next=%s' % request.path) return HttpResponseRedirect('/login/?next=%s' % request.path)
# ... # ...


...or display an error message:: ...or display an error message::


def my_view(request): def my_view(request):
if request.user.is_anonymous(): if not request.user.is_authenticated():
return render_to_response('myapp/login_error.html') return render_to_response('myapp/login_error.html')
# ... # ...


Expand Down Expand Up @@ -439,7 +444,7 @@ For example, this view checks to make sure the user is logged in and has the
permission ``polls.can_vote``:: permission ``polls.can_vote``::


def my_view(request): def my_view(request):
if request.user.is_anonymous() or not request.user.has_perm('polls.can_vote'): if not (request.user.is_authenticated() and request.user.has_perm('polls.can_vote')):
return HttpResponse("You can't vote in this poll.") return HttpResponse("You can't vote in this poll.")
# ... # ...


Expand Down Expand Up @@ -605,10 +610,10 @@ Users
The currently logged-in user, either a ``User`` instance or an``AnonymousUser`` The currently logged-in user, either a ``User`` instance or an``AnonymousUser``
instance, is stored in the template variable ``{{ user }}``:: instance, is stored in the template variable ``{{ user }}``::


{% if user.is_anonymous %} {% if user.is_authenticated %}
<p>Welcome, new user. Please log in.</p> <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
{% else %} {% else %}
<p>Welcome, {{ user.username }}. Thanks for logging in.</p> <p>Welcome, new user. Please log in.</p>
{% endif %} {% endif %}


Permissions Permissions
Expand Down
8 changes: 4 additions & 4 deletions docs/request_response.txt
Expand Up @@ -106,12 +106,12 @@ All attributes except ``session`` should be considered read-only.
A ``django.contrib.auth.models.User`` object representing the currently A ``django.contrib.auth.models.User`` object representing the currently
logged-in user. If the user isn't currently logged in, ``user`` will be set logged-in user. If the user isn't currently logged in, ``user`` will be set
to an instance of ``django.contrib.auth.models.AnonymousUser``. You to an instance of ``django.contrib.auth.models.AnonymousUser``. You
can tell them apart with ``is_anonymous()``, like so:: can tell them apart with ``is_authenticated()``, like so::


if request.user.is_anonymous(): if request.user.is_authenticated():
# Do something for anonymous users.
else:
# Do something for logged-in users. # Do something for logged-in users.
else:
# Do something for anonymous users.


``user`` is only available if your Django installation has the ``user`` is only available if your Django installation has the
``AuthenticationMiddleware`` activated. For more, see ``AuthenticationMiddleware`` activated. For more, see
Expand Down

0 comments on commit 51705f6

Please sign in to comment.