How to save data in both (user and profile) tables using django signals in a single request?

Viewed 424

I have a register form with fields(firstname, lastname, username, email, dateofbirth, phoneno.)

I have used signals to create a record in userprofile. whenever a new userdata is added to the user table

what i want is whenever user post the request. the data should get saved in user table and then the signal creates a record in profile table and then the remaining data should also get populated in there respected fields. As I'm receiving all the data from user at the registration time.

views.py

def register(request):

    if request.method == "POST":

        print(request.POST)


        first_name = request.POST.get('first-name')            <-----user table
        last_name = request.POST.get('last-name')            <-----user table
        username = request.POST.get('username')            <-----user table
        email = request.POST.get('email')            <-----user table
        gender = request.POST.get('gender')            <-----profile table
        date_of_birth = request.POST.get('date-of-birth')            <-----profile table
        address = request.POST.get('address')            <-----profile table
        phone_number = request.POST.get('mob-number')            <-----profile table

        ans_1 = request.POST.get('ans-1')            <-----profile table
        ans_2 = request.POST.get('ans-2')            <-----profile table

        User.objects.create_user(first_name=first_name, last_name=last_name, email=email, username=username, last_login=timezone.now())


    return render(request, 'authentication/register.html')

signals.py


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

@receiver(post_save, sender=User)
def save_user_info(sender, instance, **kwargs):
    instance.userinfo.save()

apps.py

class YourappConfig(AppConfig):
    ...
    def ready(self):
        import yourapp.signals
2 Answers

I don't know whether it is a good solution or not. But this work for me.

views.py

def register_user(request):

    if request.method == "POST":

        new_user  =  User(first_name = request.POST.get('first-name'),
        last_name = request.POST.get('last-name'),
        username = request.POST.get('email-mobile'),
        last_login=timezone.now()
        # password = request.POST.get('password')
        )
        new_user.set_password(request.POST.get('password'))

        new_user.gender = request.POST.get('gender')
        new_user.date_of_birth = request.POST.get('dob')
        new_user.address = request.POST.get('address')

        new_user.ans_1 = request.POST.get('ans-1')
        new_user.ans_2 = request.POST.get('ans-2')
        new_user.save()
        return redirect('auth-login')

    return render(request, 'authentication/register.html')

signals.py

@receiver(post_save, sender=User)
def create_user_info(sender, instance, created, **kwargs):
    if created:
        attrs_needed= ['gender', 'date_of_birth', 'address', 'ans_1', 'ans_2']
        UserInformation.objects.create(user=instance, gender=instance.gender, date_of_birth = instance.date_of_birth, address=instance.address, ans_1=instance.ans_1, ans_2=instance.ans_2)


post_save.connect(create_user_info, sender=User, weak=False)

apps.py

class YourappConfig(AppConfig):
    ...
    def ready(self):
        import yourapp.signals

So, what I have done here is I first took all the request data and bind it to User object. And then in signals.py I took the instance (which is passed with the post_save signal) and then while creating the Userinfo new object I also pass the fields data to it.

I could have commented but am unable to add a comment to your question. I reproduced your error but I updated app.py by adding the ready() function and adding import yourapp.signals in the AppConfig(AppConfig) class I was able to update the Profile model

class YourappConfig(AppConfig):
    ...
    def ready(self):
        import yourapp.signals
Related