Schema - Ability to change email address (primary user id) in Django
<p>Currently my  user table looks like this - (all fields are not null)</p>

<pre><code>display_name  = CharField                  # string
email_address = EmailField   (primary key) # string
password      = CharField                  # string
</code></pre>

<p>However, I have decided to add additional functionality and to allow users to change their email addresses.</p>

<p>The flow goes like this </p>

<p><a href="http://i.stack.imgur.com/rH1dn.png" rel="nofollow"><img src="http://i.stack.imgur.com/rH1dn.png" alt="enter image description here"></a></p>

<p>Does anyone have any ideas on how to do this?</p>

<p>Currently I am thinking of something like</p>

<pre><code>display_name  = CharField                  # string
email_address = EmailField   (primary key) # string
password      = CharField                  # string
pending_email = EmailField   (unique)      # string
</code></pre>

<p>And simply hold the new email address in <code>pending_email</code> before replacing the old email address in <code>email_address</code></p>

<p>But obviously this is far from perfect (e.g. <code>pending_email</code> unique constraint does not cover <code>email_address</code>)</p>

<p>Ive thought about just leaving it like this and performing more selects against the database with AJAX queries to check if the desired new email address already lives in <code>email_address</code> before allowing it to be entered into <code>pending_email</code> but this seems still vulnerable to race conditions and poor user experiences on top of being not very database friendly.</p>

<p>The standard practice in this sort of situation is to create a separate table for email addresses. That allows users to have more than one email address at a given time and one of them can be marked as default. </p>

<p>This is what <a href="https://github.com/pennersr/django-allauth/blob/master/allauth/account/models.py#L23" rel="nofollow">django-allauth</a>'s EmailAddress model looks like. In fact, unless you have a very compelling reason to write your own authentication system, I highly recommend that your swith to django allauth or any of the widely used django authentication/registration system.</p>

<pre><code>class EmailAddress(models.Model):

    user = models.ForeignKey(allauth_app_settings.USER_MODEL,
                             verbose_name=_('user'))
    email = models.EmailField(unique=app_settings.UNIQUE_EMAIL,
                              max_length=app_settings.EMAIL_MAX_LENGTH,
                              verbose_name=_('e-mail address'))
    verified = models.BooleanField(verbose_name=_('verified'), default=False)
    primary = models.BooleanField(verbose_name=_('primary'), default=False)

    objects = EmailAddressManager()
</code></pre>

python django database user schema