ValueError: Невозможно назначить объект. Пользователь должен быть экземпляром «Пользователь». - PullRequest
0 голосов
/ 30 октября 2018

Это очень странно для меня. Я устанавливаю точку останова внутри приемника сигнала Django create_customer_settings, чтобы отладить это. Приложение выдает ValueError, даже если новый объект CustomerSettings успешно создан. Когда я пытаюсь создать его во второй раз, я получаю УНИКАЛЬНУЮ ошибку ограничения, но это потому, что она уже была успешно добавлена.

Почему ValueError, когда isinstance(this_user, User) == True?

Это ошибка, которую я могу безопасно поймать и игнорировать? Это проблема, потому что идентификатор CustomerSettings отличается от идентификатора User?

create_customer_settings

@receiver(post_save, sender=User)
def create_customer_settings(sender, instance, created, **kwargs):
    if created:
      this_user = User.objects.get(id=instance.id)
      pdb.set_trace()
      CustomerSettings.objects.create(
          user=this_user, 
          email=this_user.email, 
          date_of_birth="1998-01-04", 
          in_private_mode=False
    )                                 

pdb.set_trace () вывод 1:

System check identified no issues (0 silenced).
October 29, 2018 - 23:42:57
Django version 2.1.1, using settings 'myapp.settings'
Starting development server at http://127.0.0.1:7000/
Quit the server with CONTROL-C.
> /src/myapp/myapp/models.py(36)create_customer_settings()
-> pdb.set_trace()
(Pdb) this_user
<User: new_user_8080>
(Pdb) isinstance(this_user, User)
True
(Pdb) CustomerSettings.objects.create(
    user=this_user, 
    email=this_user.email, 
    date_of_birth="1998-01-04", 
    in_private_mode=False
)                                 
*** ValueError: Cannot assign 
"<CustomerSettings: CustomerSettings object (6)>": 
"CustomerSettings.user" must be a "User" instance.

pdb.set_trace () вывод 2:

(Pdb) this_user.is_anonymous
False
(Pdb) this_user
<User: new_user_8080>
(Pdb) CustomerSettings.objects.create(
    user=this_user, 
    email=this_user.email, 
    date_of_birth="1998-01-04", 
    in_private_mode=False
)                                 
*** django.db.utils.IntegrityError: 
UNIQUE constraint failed: myapp_customersettings.user_id
(Pdb) CustomerSettings.objects.all()
<QuerySet [<CustomerSettings: CustomerSettings object (1)>,
<CustomerSettings: CustomerSettings object (2)>,
<CustomerSettings: CustomerSettings object (3)>,
<CustomerSettings: CustomerSettings object (4)>,
<CustomerSettings: CustomerSettings object (5)>,
<CustomerSettings: CustomerSettings object (6)>]>
(Pdb) CustomerSettings.objects.all().values()
<QuerySet [
{'id': 1, 'user_id': 1, 'timezone': 'America/New_York', 'email':...
    ...
    ...
    ... 
, {'id': 6, 'user_id': 15, 'timezone': '', 'email': 'new_user_8080@gmail.com', 
'email_confirmed': False, 'date_of_birth': datetime.date(1998, 1, 4), 'first_name': '', 'last_name': '', 'in_private_mode': False}]>
(Pdb) CustomerSettings.objects.filter(user_id=15)
<QuerySet [<CustomerSettings: CustomerSettings object (6)>]>
(Pdb) CustomerSettings.objects.filter(user_id=15).values()
<QuerySet [{'id': 6, 'user_id': 15, 'timezone': '', 'email': 'new_user_8080@gmail.com', 'email_confirmed': False, 'date_of_birth': datetime.date(1998, 1, 4), 'first_name': '', 'last_name': '', 'in_private_mode': False}]>
(Pdb) CustomerSettings.objects.filter(user_id=15).values()[0]
{'id': 6, 'user_id': 15, 'timezone': '', 'email': 'new_user_8080@gmail.com', 'email_confirmed': False, 'date_of_birth': datetime.date(1998, 1, 4), 'first_name': '', 'last_name': '', 'in_private_mode': False}
(Pdb) CustomerSettings.objects.filter(user_id=15).values()[0]['id']
6
(Pdb) User.objects.get(id=15)
<User: new_user_8080>
(Pdb) 

CustomerSettings Модель:

class CustomerSettings(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, unique=True, null=False, blank=False)
    timezone = models.CharField(max_length=50, choices=TIMEZONE_CHOICES, blank=False, null=False)
    email = models.EmailField(
            verbose_name='email address',
            max_length=255, blank=False, null=False,
            unique=True)
    email_confirmed = models.BooleanField(default=False)
    date_of_birth = models.DateField()
    first_name = models.CharField(max_length=50, null=False, blank=False)
    last_name = models.CharField(max_length=50, null=False, blank=False)
    in_private_mode = models.BooleanField()

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Я долго и пристально смотрел на трассировку. Метод, который работал ранее для update_customer_settings, вызывался после успешного создания модели CustomerSettings после события post_save с помощью User, что в данном случае действительно было CustomerSettings.

Я прошу прощения за путаницу. Вы все указали мне в правильном направлении, спасибо. Мне нужно справиться с этим совершенно по-другому.

отслеживающий

File "/Users/my_folder/my_app/my_app/models.py", line 44, in update_customer_settings
CustomerSettings.objects.create(user=instance)
ValueError: Cannot assign "<CustomerSettings: CustomerSettings object (14)>": "CustomerSettings.user" must be a "User" instance.

update_customer_settings

@receiver(post_save, sender=CustomerSettings)
def update_customer_settings(sender, instance, created, **kwargs):
    if created:
        CustomerSettings.objects.create(user=instance)
    instance.customersettings.save()
0 голосов
/ 30 октября 2018

Дважды проверьте, что код, который вы опубликовали, является тем, что у вас работает. Сообщение об ошибке ValueError: Cannot assign "<CustomerSettings: CustomerSettings object (6)>": "CustomerSettings.user" must be a "User" instance означает, что вы пытаетесь создать экземпляр CustomerSettings, в котором свойство user имеет экземпляр CustomerSettings, идентификатор которого равен 6.

Полагаю, есть разрыв между тем, что у вас есть, и тем, что вы опубликовали. Если нет, то что-то вызывает create_customer_settings, где аргумент instance является экземпляром CustomerSettings.

...