From 63696982b8deb33fa4840dbe57ccbd3cf3dea9cb Mon Sep 17 00:00:00 2001 From: Tim Graham Date: Wed, 23 Nov 2016 15:03:33 -0500 Subject: [PATCH] [1.10.x] Normalized casing of "custom user model". Backport of 93a081946d92da010c7de62dc58e697c6c33e5d3 from master --- docs/howto/deployment/wsgi/apache-auth.txt | 2 +- docs/ref/contrib/auth.txt | 23 ++-- docs/releases/1.5.txt | 6 +- docs/releases/1.6.txt | 2 +- docs/topics/auth/customizing.txt | 127 ++++++++++----------- docs/topics/auth/default.txt | 16 +-- tests/auth_tests/models/custom_user.py | 2 +- tests/auth_tests/test_management.py | 2 +- 8 files changed, 88 insertions(+), 92 deletions(-) diff --git a/docs/howto/deployment/wsgi/apache-auth.txt b/docs/howto/deployment/wsgi/apache-auth.txt index 3d4b35fd04..5f134209f0 100644 --- a/docs/howto/deployment/wsgi/apache-auth.txt +++ b/docs/howto/deployment/wsgi/apache-auth.txt @@ -15,7 +15,7 @@ version >= 2.2 and mod_wsgi >= 2.0. For example, you could: * Allow certain users to connect to a WebDAV share created with mod_dav_. .. note:: - If you have installed a :ref:`custom User model ` and + If you have installed a :ref:`custom user model ` and want to use this default auth handler, it must support an ``is_active`` attribute. If you want to use group based authorization, your custom user must have a relation named 'groups', referring to a related object that has diff --git a/docs/ref/contrib/auth.txt b/docs/ref/contrib/auth.txt index c0e4f5bdc6..d68c062b68 100644 --- a/docs/ref/contrib/auth.txt +++ b/docs/ref/contrib/auth.txt @@ -183,9 +183,9 @@ Methods .. method:: get_username() - Returns the username for the user. Since the User model can be swapped - out, you should use this method instead of referencing the username - attribute directly. + Returns the username for the user. Since the ``User`` model can be + swapped out, you should use this method instead of referencing the + username attribute directly. .. method:: get_full_name() @@ -305,7 +305,7 @@ Manager methods The ``extra_fields`` keyword arguments are passed through to the :class:`~django.contrib.auth.models.User`’s ``__init__`` method to - allow setting arbitrary fields on a :ref:`custom User model + allow setting arbitrary fields on a :ref:`custom user model `. See :ref:`Creating users ` for example usage. @@ -599,16 +599,14 @@ The following backends are available in :mod:`django.contrib.auth.backends`: .. attribute:: RemoteUserBackend.create_unknown_user - ``True`` or ``False``. Determines whether or not a - :class:`~django.contrib.auth.models.User` object is created if not already - in the database. Defaults to ``True``. + ``True`` or ``False``. Determines whether or not a user object is created + if not already in the database Defaults to ``True``. .. method:: RemoteUserBackend.authenticate(remote_user) The username passed as ``remote_user`` is considered trusted. This method - simply returns the ``User`` object with the given username, creating a new - ``User`` object if :attr:`~RemoteUserBackend.create_unknown_user` is - ``True``. + simply returns the user object with the given username, creating a new + user object if :attr:`~RemoteUserBackend.create_unknown_user` is ``True``. Returns ``None`` if :attr:`~RemoteUserBackend.create_unknown_user` is ``False`` and a ``User`` object with the given username is not found in the @@ -617,9 +615,8 @@ The following backends are available in :mod:`django.contrib.auth.backends`: .. method:: RemoteUserBackend.clean_username(username) Performs any cleaning on the ``username`` (e.g. stripping LDAP DN - information) prior to using it to get or create a - :class:`~django.contrib.auth.models.User` object. Returns the cleaned - username. + information) prior to using it to get or create a user object. Returns the + cleaned username. .. method:: RemoteUserBackend.configure_user(user) diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt index 9d63f3d573..cbd1d48cfe 100644 --- a/docs/releases/1.5.txt +++ b/docs/releases/1.5.txt @@ -133,7 +133,7 @@ you may need to make some changes to the way you reference User instances. You should also document any specific features of the User model that your application relies upon. -See the :ref:`documentation on custom User models ` for +See the :ref:`documentation on custom user models ` for more details. Support for saving a subset of model's fields @@ -560,7 +560,7 @@ Prior to Django 1.5, if you attempted to log into the admin interface and mistakenly used your email address instead of your username, the admin interface would provide a warning advising that your email address was not your username. In Django 1.5, the introduction of -:ref:`custom User models ` has required the removal of this +:ref:`custom user models ` has required the removal of this warning. This doesn't change the login behavior of the admin site; it only affects the warning message that is displayed under one particular mode of login failure. @@ -741,7 +741,7 @@ framework. ``AUTH_PROFILE_MODULE`` ----------------------- -With the introduction of :ref:`custom User models `, there is +With the introduction of :ref:`custom user models `, there is no longer any need for a built-in mechanism to store user profile data. You can still define user profiles models that have a one-to-one relation with diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt index 1be016e336..b23c4f3be2 100644 --- a/docs/releases/1.6.txt +++ b/docs/releases/1.6.txt @@ -448,7 +448,7 @@ removed and the standalone GeoDjango tests execution setup it implemented isn't supported anymore. To run the GeoDjango tests simply use the new ``DiscoverRunner`` and specify the ``django.contrib.gis`` app. -Custom User models in tests +Custom user models in tests --------------------------- The introduction of the new test runner has also slightly changed the way that diff --git a/docs/topics/auth/customizing.txt b/docs/topics/auth/customizing.txt index 398513d948..9b73516fbf 100644 --- a/docs/topics/auth/customizing.txt +++ b/docs/topics/auth/customizing.txt @@ -9,14 +9,14 @@ provided system are extensible or replaceable. This document provides details about how the auth system can be customized. :ref:`Authentication backends ` provide an extensible -system for when a username and password stored with the User model need -to be authenticated against a different service than Django's default. +system for when a username and password stored with the user model need to be +authenticated against a different service than Django's default. -You can give your models :ref:`custom permissions ` that can be -checked through Django's authorization system. +You can give your models :ref:`custom permissions ` that +can be checked through Django's authorization system. -You can :ref:`extend ` the default User model, or :ref:`substitute -` a completely customized model. +You can :ref:`extend ` the default ``User`` model, or +:ref:`substitute ` a completely customized model. .. _authentication-backends: @@ -93,27 +93,27 @@ An authentication backend is a class that implements two required methods: optional permission related :ref:`authorization methods `. The ``get_user`` method takes a ``user_id`` -- which could be a username, -database ID or whatever, but has to be the primary key of your ``User`` object --- and returns a ``User`` object. +database ID or whatever, but has to be the primary key of your user object -- +and returns a user object. The ``authenticate`` method takes credentials as keyword arguments. Most of the time, it'll just look like this:: class MyBackend(object): def authenticate(self, username=None, password=None): - # Check the username/password and return a User. + # Check the username/password and return a user. ... But it could also authenticate a token, like so:: class MyBackend(object): def authenticate(self, token=None): - # Check the token and return a User. + # Check the token and return a user. ... -Either way, ``authenticate`` should check the credentials it gets, and it -should return a ``User`` object that matches those credentials, if the -credentials are valid. If they're not valid, it should return ``None``. +Either way, ``authenticate()`` should check the credentials it gets and return +a user object that matches those credentials if the credentials are valid. If +they're not valid, it should return ``None``. The Django admin is tightly coupled to the Django :ref:`User object `. The best way to deal with this is to create a Django ``User`` @@ -354,17 +354,17 @@ add it to a ``UserAdmin`` class which is registered with the admin.site.unregister(User) admin.site.register(User, UserAdmin) -These profile models are not special in any way - they are just Django models that -happen to have a one-to-one link with a User model. As such, they do not get +These profile models are not special in any way - they are just Django models +that happen to have a one-to-one link with a user model. As such, they aren't auto created when a user is created, but a :attr:`django.db.models.signals.post_save` could be used to create or update related models as appropriate. -Note that using related models results in additional queries or joins to -retrieve the related data, and depending on your needs substituting the User -model and adding the related fields may be your better option. However -existing links to the default User model within your project's apps may justify -the extra database load. +Using related models results in additional queries or joins to retrieve the +related data. Depending on your needs, a custom user model that includes the +related fields may be your better option, however, existing relations to the +default user model within your project's apps may justify the extra database +load. .. _auth-custom-user: @@ -376,14 +376,14 @@ built-in :class:`~django.contrib.auth.models.User` model is not always appropriate. For instance, on some sites it makes more sense to use an email address as your identification token instead of a username. -Django allows you to override the default User model by providing a value for +Django allows you to override the default user model by providing a value for the :setting:`AUTH_USER_MODEL` setting that references a custom model:: AUTH_USER_MODEL = 'myapp.MyUser' This dotted pair describes the name of the Django app (which must be in your :setting:`INSTALLED_APPS`), and the name of the Django model that you wish to -use as your User model. +use as your user model. Using a custom user model when starting a project ------------------------------------------------- @@ -443,17 +443,17 @@ Referencing the ``User`` model If you reference :class:`~django.contrib.auth.models.User` directly (for example, by referring to it in a foreign key), your code will not work in projects where the :setting:`AUTH_USER_MODEL` setting has been changed to a -different User model. +different user model. .. function:: get_user_model() Instead of referring to :class:`~django.contrib.auth.models.User` directly, you should reference the user model using ``django.contrib.auth.get_user_model()``. This method will return the - currently active User model -- the custom User model if one is specified, or + currently active user model -- the custom user model if one is specified, or :class:`~django.contrib.auth.models.User` otherwise. - When you define a foreign key or many-to-many relations to the User model, + When you define a foreign key or many-to-many relations to the user model, you should specify the custom model using the :setting:`AUTH_USER_MODEL` setting. For example:: @@ -466,7 +466,7 @@ different User model. on_delete=models.CASCADE, ) - When connecting to signals sent by the ``User`` model, you should specify + When connecting to signals sent by the user model, you should specify the custom model using the :setting:`AUTH_USER_MODEL` setting. For example:: from django.conf import settings @@ -477,27 +477,27 @@ different User model. post_save.connect(post_save_receiver, sender=settings.AUTH_USER_MODEL) - Generally speaking, you should reference the User model with the + Generally speaking, you should reference the user model with the :setting:`AUTH_USER_MODEL` setting in code that is executed at import time. ``get_user_model()`` only works once Django has imported all models. .. _specifying-custom-user-model: -Specifying a custom ``User`` model ----------------------------------- +Specifying a custom user model +------------------------------ .. admonition:: Model design considerations Think carefully before handling information not directly related to - authentication in your custom User Model. + authentication in your custom user model. It may be better to store app-specific user information in a model - that has a relation with the User model. That allows each app to specify + that has a relation with the user model. That allows each app to specify its own user data requirements without risking conflicts with other apps. On the other hand, queries to retrieve this related information will involve a database join, which may have an effect on performance. -Django expects your custom User model to meet some minimum requirements. +Django expects your custom user model to meet some minimum requirements. #. If you use the default authentication backend, then your model must have a single unique field that can be used for identification purposes. This can @@ -512,10 +512,10 @@ Django expects your custom User model to meet some minimum requirements. what these two methods return - if you want, they can return exactly the same value. -The easiest way to construct a compliant custom User model is to inherit from +The easiest way to construct a compliant custom user model is to inherit from :class:`~django.contrib.auth.models.AbstractBaseUser`. :class:`~django.contrib.auth.models.AbstractBaseUser` provides the core -implementation of a ``User`` model, including hashed passwords and tokenized +implementation of a user model, including hashed passwords and tokenized password resets. You must then provide some key implementation details: .. currentmodule:: django.contrib.auth @@ -524,7 +524,7 @@ password resets. You must then provide some key implementation details: .. attribute:: USERNAME_FIELD - A string describing the name of the field on the User model that is + A string describing the name of the field on the user model that is used as the unique identifier. This will usually be a username of some kind, but it can also be an email address, or any other unique identifier. The field *must* be unique (i.e., have ``unique=True`` set @@ -557,7 +557,7 @@ password resets. You must then provide some key implementation details: ``REQUIRED_FIELDS`` has no effect in other parts of Django, like creating a user in the admin. - For example, here is the partial definition for a ``User`` model that + For example, here is the partial definition for a user model that defines two required fields - a date of birth and height:: class MyUser(AbstractBaseUser): @@ -569,8 +569,8 @@ password resets. You must then provide some key implementation details: .. note:: - ``REQUIRED_FIELDS`` must contain all required fields on your - ``User`` model, but should *not* contain the ``USERNAME_FIELD`` or + ``REQUIRED_FIELDS`` must contain all required fields on your user + model, but should *not* contain the ``USERNAME_FIELD`` or ``password`` as these fields will always be prompted for. :attr:`REQUIRED_FIELDS` now supports @@ -705,14 +705,13 @@ The following attributes and methods are available on any subclass of Returns an HMAC of the password field. Used for :ref:`session-invalidation-on-password-change`. -You should also define a custom manager for your ``User`` model. If your -``User`` model defines ``username``, ``email``, ``is_staff``, ``is_active``, -``is_superuser``, ``last_login``, and ``date_joined`` fields the same as -Django's default ``User``, you can just install Django's -:class:`~django.contrib.auth.models.UserManager`; however, if your ``User`` -model defines different fields, you will need to define a custom manager that -extends :class:`~django.contrib.auth.models.BaseUserManager` providing two -additional methods: +You should also define a custom manager for your user model. If your user model +defines ``username``, ``email``, ``is_staff``, ``is_active``, ``is_superuser``, +``last_login``, and ``date_joined`` fields the same as Django's default user, +you can just install Django's :class:`~django.contrib.auth.models.UserManager`; +however, if your user model defines different fields, you'll need to define a +custom manager that extends :class:`~django.contrib.auth.models.BaseUserManager` +providing two additional methods: .. class:: models.CustomUserManager @@ -827,9 +826,9 @@ can extend these forms in this manner:: Custom users and :mod:`django.contrib.admin` -------------------------------------------- -If you want your custom User model to also work with Admin, your User model must -define some additional attributes and methods. These methods allow the admin to -control access of the User to admin content: +If you want your custom user model to also work with the admin, your user model +must define some additional attributes and methods. These methods allow the +admin to control access of the user to admin content: .. class:: models.CustomUser @@ -852,23 +851,23 @@ control access of the User to admin content: Returns ``True`` if the user has permission to access models in the given app. -You will also need to register your custom User model with the admin. If -your custom User model extends ``django.contrib.auth.models.AbstractUser``, +You will also need to register your custom user model with the admin. If +your custom user model extends ``django.contrib.auth.models.AbstractUser``, you can use Django's existing ``django.contrib.auth.admin.UserAdmin`` -class. However, if your User model extends +class. However, if your user model extends :class:`~django.contrib.auth.models.AbstractBaseUser`, you'll need to define a custom ``ModelAdmin`` class. It may be possible to subclass the default ``django.contrib.auth.admin.UserAdmin``; however, you'll need to override any of the definitions that refer to fields on ``django.contrib.auth.models.AbstractUser`` that aren't on your -custom User class. +custom user class. Custom users and permissions ---------------------------- -To make it easy to include Django's permission framework into your own User +To make it easy to include Django's permission framework into your own user class, Django provides :class:`~django.contrib.auth.models.PermissionsMixin`. -This is an abstract model you can include in the class hierarchy for your User +This is an abstract model you can include in the class hierarchy for your user model, giving you all the methods and database fields necessary to support Django's permission model. @@ -929,21 +928,21 @@ methods and attributes: If you don't include the :class:`~django.contrib.auth.models.PermissionsMixin`, you must ensure you don't invoke the permissions methods on ``ModelBackend``. ``ModelBackend`` - assumes that certain fields are available on your user model. If your - ``User`` model doesn't provide those fields, you will receive database - errors when you check permissions. + assumes that certain fields are available on your user model. If your user + model doesn't provide those fields, you'll receive database errors when + you check permissions. Custom users and proxy models ----------------------------- -One limitation of custom User models is that installing a custom User model +One limitation of custom user models is that installing a custom user model will break any proxy model extending :class:`~django.contrib.auth.models.User`. -Proxy models must be based on a concrete base class; by defining a custom User +Proxy models must be based on a concrete base class; by defining a custom user model, you remove the ability of Django to reliably identify the base class. If your project uses proxy models, you must either modify the proxy to extend -the User model that is currently in use in your project, or merge your proxy's -behavior into your User subclass. +the user model that's in use in your project, or merge your proxy's behavior +into your :class:`~django.contrib.auth.models.User` subclass. A full example -------------- @@ -952,7 +951,7 @@ Here is an example of an admin-compliant custom user app. This user model uses an email address as the username, and has a required date of birth; it provides no permission checking, beyond a simple ``admin`` flag on the user account. This model would be compatible with all the built-in auth forms and -views, except for the User creation forms. This example illustrates how most of +views, except for the user creation forms. This example illustrates how most of the components work together, but is not intended to be copied directly into projects for production use. @@ -1040,7 +1039,7 @@ authentication app:: # Simplest possible answer: All admins are staff return self.is_admin -Then, to register this custom User model with Django's admin, the following +Then, to register this custom user model with Django's admin, the following code would be required in the app's ``admin.py`` file:: from django import forms diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt index 2bb7883f75..6c2a3443bf 100644 --- a/docs/topics/auth/default.txt +++ b/docs/topics/auth/default.txt @@ -86,7 +86,7 @@ function is used when creating a user. To change a user's password, you have several options: :djadmin:`manage.py changepassword *username* ` offers a method -of changing a User's password from the command line. It prompts you to +of changing a user's password from the command line. It prompts you to change the password of a given user which you must enter twice. If they both match, the new password will be changed immediately. If you do not supply a user, the command will attempt to change the password @@ -260,12 +260,12 @@ Permission caching ------------------ The :class:`~django.contrib.auth.backends.ModelBackend` caches permissions on -the ``User`` object after the first time they need to be fetched for a -permissions check. This is typically fine for the request-response cycle since -permissions are not typically checked immediately after they are added (in the -admin, for example). If you are adding permissions and checking them immediately +the user object after the first time they need to be fetched for a permissions +check. This is typically fine for the request-response cycle since permissions +aren't typically checked immediately after they are added (in the admin, for +example). If you are adding permissions and checking them immediately afterward, in a test or view for example, the easiest solution is to re-fetch -the ``User`` from the database. For example:: +the user from the database. For example:: from django.contrib.auth.models import Permission, User from django.shortcuts import get_object_or_404 @@ -373,7 +373,7 @@ is selected as follows: pairing :func:`~django.contrib.auth.authenticate()` and :func:`~django.contrib.auth.login()`: :func:`~django.contrib.auth.authenticate()` - sets the ``user.backend`` attribute on the ``User`` object it returns. + sets the ``user.backend`` attribute on the user object it returns. #. Use the ``backend`` in :setting:`AUTHENTICATION_BACKENDS`, if there is only one. #. Otherwise, raise an exception. @@ -1505,7 +1505,7 @@ provides several built-in forms located in :mod:`django.contrib.auth.forms`: .. note:: The built-in authentication forms make certain assumptions about the user - model that they are working with. If you're using a :ref:`custom User model + model that they are working with. If you're using a :ref:`custom user model `, it may be necessary to define your own forms for the authentication system. For more information, refer to the documentation about :ref:`using the built-in authentication forms with custom user models diff --git a/tests/auth_tests/models/custom_user.py b/tests/auth_tests/models/custom_user.py index 469cada31e..fac51064ba 100644 --- a/tests/auth_tests/models/custom_user.py +++ b/tests/auth_tests/models/custom_user.py @@ -6,7 +6,7 @@ from django.db import models from django.utils.encoding import python_2_unicode_compatible -# The custom User uses email as the unique identifier, and requires +# The custom user uses email as the unique identifier, and requires # that every user provide a date of birth. This lets us test # changes in username datatype, and non-text required fields. class CustomUserManager(BaseUserManager): diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 8eff655c99..823bb02a2a 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -263,7 +263,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): @override_settings(AUTH_USER_MODEL='auth_tests.CustomUser') def test_swappable_user(self): - "A superuser can be created when a custom User model is in use" + "A superuser can be created when a custom user model is in use" # We can use the management command to create a superuser # We skip validation because the temporary substitution of the # swappable User model messes with validation.