# Advanced Usage

## Custom User Models

If you use a custom user model you need to specify what field represents the `username`, if any. Here, `username` really refers to the field representing the nickname that the user uses to login, and not to some unique identifier (possibly including an email address) as is the case for Django’s `AbstractBaseUser.USERNAME_FIELD`.

Therefore, if your custom user model does not have a `username` field (again, not to be mistaken with an email address or user id), you will need to set `ACCOUNT_USER_MODEL_USERNAME_FIELD` to `None`. This will disable username related functionality in `allauth`. Remember to also set `ACCOUNT_USERNAME_REQUIRED` to `False`.

Similarly, you will need to set `ACCOUNT_USER_MODEL_EMAIL_FIELD` to `None` or to the proper field (if other than `email`).

For example, if you want to use a custom user model that has `email` as the identifying field, and you don’t want to collect usernames, you need the following in your settings.py:

    ACCOUNT_USER_MODEL_USERNAME_FIELD = None
    ACCOUNT_EMAIL_REQUIRED = True
    ACCOUNT_USERNAME_REQUIRED = False
    ACCOUNT_AUTHENTICATION_METHOD = 'email'

## Creating and Populating User instances

The following adapter methods can be used to intervene in how User instances are created and populated with data

- `allauth.account.adapter.DefaultAccountAdapter`:

  - `is_open_for_signup(self, request)`: The default function returns `True`. You can override this method by returning `False` if you want to disable account signup.

  - `new_user(self, request)`: Instantiates a new, empty `User`.

  - `save_user(self, request, user, form)`: Populates and saves the `User` instance using information provided in the signup form.

  - `populate_username(self, request, user)`: Fills in a valid username, if required and missing. If the username is already present, then it is assumed to be valid (unique).

  - `confirm_email(self, request, email_address)`: Marks the email address as confirmed and saves to the db.

  - `generate_unique_username(self, txts, regex=None)`: Returns a unique username from the combination of strings present in txts iterable. A regex pattern can be passed to the method to make sure the generated username matches it.

## Invitations

Invitation handling is not supported, and most likely will not be any time soon. An invitation app could cover anything ranging from invitations of new users, to invitations of existing users to participate in restricted parts of the site. All in all, the scope of invitation handling is large enough to warrant being addressed in an app of its own.

Still, everything is in place to easily hook up any third party invitation app. The account adapter (`allauth.account.adapter.DefaultAccountAdapter`) offers the following methods:

- `is_open_for_signup(self, request)`. You can override this method to, for example, inspect the session to check if an invitation was accepted.

- `stash_verified_email(self, request, email)`. If an invitation was accepted by following a link in an email, then there is no need to send email verification mails after the signup is completed. Use this method to record the fact that an email address was verified.

## Custom Redirects

If redirecting to statically configurable URLs (as specified in your project settings) is not flexible enough, then you can override the following adapter methods:

- `allauth.account.adapter.DefaultAccountAdapter`:

  - `get_login_redirect_url(self, request)`

  - `get_logout_redirect_url(self, request)`

  - `get_email_verification_redirect_url(self, email_address)`

  - `get_signup_redirect_url(self, request)`

For example, redirecting to `/accounts/<username>/` can be implemented as follows:

    # project/settings.py:
    ACCOUNT_ADAPTER = 'project.users.adapter.MyAccountAdapter'

    # project/users/adapter.py:
    from django.conf import settings
    from allauth.account.adapter import DefaultAccountAdapter

    class MyAccountAdapter(DefaultAccountAdapter):

        def get_login_redirect_url(self, request):
            path = "/accounts/{username}/"
            return path.format(username=request.user.username)