Ошибка дублированного ключа при сохранении нового пользователя - PullRequest
1 голос
/ 08 ноября 2019

Я пытаюсь сохранить пользователя и профиль в django, которые связаны друг с другом, используя oneToOneField, но я получаю сообщение об ошибке, говорящее:

значение дублированного ключа нарушает ограничение уникальности "auth_user_username_key

даже если у меня нет дубликатов.

Я также получаю эту ошибку:

значение дублированного ключа нарушает уникальное ограничение "api_profile_user_id_key" DETAIL: Key (user_id) = (9) уже существует.

Вот мой код:

model.py

from django.db import models
from django.contrib.auth.models import User
from django.db.models import CharField, OneToOneField
from django.db.models.signals import post_save
from django.dispatch import receiver


class Profile(models.Model):
    user = OneToOneField(User, on_delete=models.CASCADE)
    phone_number = CharField(max_length=20)
    account_type = CharField(max_length=10, default='basic')
    facebook_id = CharField(max_length=20, blank=True)
    google_id = CharField(max_length=20, blank=True)
    notification_id = CharField(max_length=40, blank=True)
    # TODO add account info and watchlist

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


@receiver(post_save, sender=User)
def user_save(sender, instance, **kwargs):
    Profile.objects.create(user=instance)

view.py:

@api_view(['POST'])
def sign_up(request):
    data = request.data
    user = User.objects.create_user(username=data['username'],
                                    password=data['password'],
                                    first_name=data['first_name'],
                                    last_name=data['last_name'],
                                    email=data['email']
                                    )
    user.profile.phone_number = data['phone_number']
    user.save()
    return Response('hey')

Я думаю, что проблема в приемнике post_save, однако я не уверен.

1 Ответ

2 голосов
/ 08 ноября 2019

create_user также вызывает save (), затем вы также вызываете user.save(), сигнал post_save вызывается дважды для одного пользователя, вы получаете ошибку, поскольку для одного пользователя создаются два объекта профиля

Вы можете сделать:

@receiver(post_save, sender=User)
def user_save(sender, instance, **kwargs):
    Profile.objects.get_or_create(user=instance)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...