How to insert a row in another table once a user is created

1,694 views
Skip to first unread message

Prithviraj Mitra

unread,
Aug 11, 2017, 2:32:01 PM8/11/17
to Django users
I am a fresher in django. I am using django 1.10 with allauth app which takes care of frontend registration, sending user confirmation email,validation, login with email etc. So it all works in the frontend. In the backend I managed to change the user creation form by adding an extra field email.

The allauth app inserts 3 rows in 3 tables when a user is created in the frontend.

1. auth_user
2. account_emailaddress
3. account_emailconfirmation

When adding a user from admin it creates a row in auth_user and general_userprofile(extending django user model) table. I would like to insert a row in account_emailaddress table whenever a user is created via admin.

Fields in account_emailaddress are--

id
email
verified
primary
user_id

models.py looks like this --

from __future__ import unicode_literals

from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
from django.db.models.signals import post_save
from django.dispatch import receiver
from ciasroot.util import HashedPk
from phonenumber_field.modelfields import PhoneNumberField
import math, decimal, datetime, os


User._meta.get_field('email').blank = False
User._meta.get_field('email')._unique = True




class EmailAddress(models.Model):
    verified
= models.BooleanField(verbose_name=_('verified'), default=True)
    primary
= models.BooleanField(verbose_name=_('primary'), default=True)


class UserProfile(models.Model, HashedPk):
    user
= models.OneToOneField(User, unique=True, related_name ='profile')
    job_title
= models.CharField(max_length=128, blank=True, null=False, default="")
    website
= models.URLField(max_length=255, blank=True, null=True)
    organisation
= models.CharField(max_length=50, blank=True, null=True, default="")
    phone_number
= PhoneNumberField( blank=True, null=True)


@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
   
if created:
       
UserProfile.objects.create(user=instance)




def __str__(self):
   
return self.user.get_full_name()


def save(self, *args, **kwargs):
   
super(UserProfile, self).save(*args, **kwargs)



How can I fetch userid and email under class EmailAddress and save it to the table.

Any help is highly appreciated.

Derek

unread,
Aug 12, 2017, 11:58:10 AM8/12/17
to Django users
I am not exactly sure about your use case description, but it seems as if your EmailAddress table is incomplete - suggest:

class EmailAddress(models.Model):

    user 
= models.OneToOneField(User, unique=True, related_name ='profile')

    verified 
= models.BooleanField(verbose_name=_('verified'), default=True)
    primary 
= models.BooleanField(verbose_name=_('primary'), default=True)

Then you can extend the profile to have (for example):

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    
if created:
        
UserProfile.objects.create(user=instance)
        EmailAddress.objects.create(user=instance, verified=False)

Otherwise the  EmailAddress class seems to be unrelated to anything, which does not make sense for a relational database.

Prithviraj Mitra

unread,
Aug 12, 2017, 12:15:58 PM8/12/17
to Django users
Hi Derek,

Many thanks for your suggestion.

I made some progress since I posted this topic. The new row has been created in EmailAddress  table but the email is blank. I can't find a solid reason. In the admin user creation form there is an email field and the table auth_user has got the email. So why the EmailAddress model is not getting the email value. As the admin is creating the user so no verification is needed. So field verified is true.

Updated code from models.py

class EmailAddress(models.Model, HashedPk):
 user
= models.OneToOneField(User, unique=True, related_name ='address')
 email
= models.EmailField()

 verified
= models.BooleanField(verbose_name=_('verified'), default=True)
 primary
= models.BooleanField(verbose_name=_('primary'), default=True)


 
class Meta:
 db_table
= 'account_emailaddress'



class UserProfile(models.Model, HashedPk):
 user
= models.OneToOneField(User, unique=True, related_name ='profile')
 job_title
= models.CharField(max_length=128, blank=True, null=False, default="")
 website
= models.URLField(max_length=255, blank=True, null=True)
 organisation
= models.CharField(max_length=50, blank=True, null=True, default="")
 phone_number
= PhoneNumberField( blank=True, null=True)


@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
 
if created:
 
UserProfile.objects.create(user=instance)

 
EmailAddress.objects.create(user=instance)

In userprofile model there is no email though. Is there any way I can pass email to the EmailAddress model.

Prithviraj Mitra

unread,
Aug 12, 2017, 12:46:08 PM8/12/17
to Django users
I have got some updates.

Basically what I want is if admin creates a user then no verification is needed. He/she can straight go to the login page and login with the email and password which was emailed to the user.(I need to do this email part later though)

Now another issue has raised with this line --
EmailAddress.objects.create(user=instance, verified=False)


When the user tries to signup from the frontend then there is a error --

  assert not EmailAddress.objects.filter(user=user).exists()
AssertionError

Because my code has already created a row in EmailAddress table and django-allauth app is trying to insert the same row again. May be that's why?



rday, 12 August 2017 16:58:10 UTC+1, Derek wrote:

Prithviraj Mitra

unread,
Aug 12, 2017, 3:44:38 PM8/12/17
to Django users
All good. It works now.

It has to be EmailAddress.objects.create(user=instance, email=instance.email)

Many thanks for your input.
Reply all
Reply to author
Forward
0 new messages