简体   繁体   中英

How do I solve the error 'IntegrityError at /admin/auth/user/add/ UNIQUE constraint failed: user_details_profile.phone' in Django?

I am trying to add a new user via the built-in django admin but I keep getting this error. Even trying to create a superuser via the terminal gives the same error. All other models not associated with the user work fine. The code inside my models.py file is as follows.

from django.db import models
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from django.dispatch import receiver
from django.core.exceptions import ObjectDoesNotExist
from general.models import Ward

# Create your models here.
class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    firstname = models.CharField(max_length=20)
    middlename = models.CharField(max_length=20)
    lastname = models.CharField(max_length=20)
    loc_id = models.CharField(max_length=8, unique=True)
    ward = models.ForeignKey(Ward, related_name="wards", null=True, on_delete=models.SET_NULL)
    phone = models.CharField(max_length=10, unique=True)
    address = models.CharField(max_length=255)
    postal_code = models.CharField(max_length=15)

    def __str__(self):
        return "{} {}".format(self.user.first_name, self.user.last_name)

    class Meta:
        verbose_name_plural = "Personal information"

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    try:
        instance.profile.save()
    except ObjectDoesNotExist:
        Profile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    try:
        instance.profile.save()
    except ObjectDoesNotExist:
        Profile.objects.create(user=instance)

The error traceback:

Environment:
Request Method: POST
Request URL: http://localhost:8000/admin/auth/user/add/

Django Version: 2.1.1
Python Version: 3.6.0
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework',
 'general',
 'user_details']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "C:\xampp\htdocs\python\projects\tanariver\user_details\models.py" in create_user_profile
  30.         instance.profile.save()

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\models\fields\related_descriptors.py" in __get__
  414.                     self.related.get_accessor_name()

During handling of the above exception (User has no profile.), another exception occurred:

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\backends\utils.py" in _execute
  85.                 return self.cursor.execute(sql, params)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\backends\sqlite3\base.py" in execute
  296.         return Database.Cursor.execute(self, query, params)

The above exception (UNIQUE constraint failed: user_details_profile.phone) was the direct cause of the following exception:

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\core\handlers\exception.py" in inner
  34.             response = get_response(request)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\core\handlers\base.py" in _get_response
  126.                 response = self.process_exception_by_middleware(e, request)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\core\handlers\base.py" in _get_response
  124.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\contrib\admin\options.py" in wrapper
  604.                 return self.admin_site.admin_view(view)(*args, **kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\views\decorators\cache.py" in _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\contrib\admin\sites.py" in inner
  223.             return view(request, *args, **kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\utils\decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\views\decorators\debug.py" in sensitive_post_parameters_wrapper
  76.             return view(request, *args, **kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\utils\decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\contrib\auth\admin.py" in add_view
  98.             return self._add_view(request, form_url, extra_context)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\contrib\auth\admin.py" in _add_view
  125.         return super().add_view(request, form_url, extra_context)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\contrib\admin\options.py" in add_view
  1636.         return self.changeform_view(request, None, form_url, extra_context)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\utils\decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\utils\decorators.py" in _wrapped_view
  142.                     response = view_func(request, *args, **kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\contrib\admin\options.py" in changeform_view
  1525.             return self._changeform_view(request, object_id, form_url, extra_context)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\contrib\admin\options.py" in _changeform_view
  1564.                 self.save_model(request, new_object, form, not add)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\contrib\admin\options.py" in save_model
  1091.         obj.save()

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\contrib\auth\base_user.py" in save
  73.         super().save(*args, **kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\models\base.py" in save
  718.                        force_update=force_update, update_fields=update_fields)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\models\base.py" in save_base
  758.                 update_fields=update_fields, raw=raw, using=using,

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\dispatch\dispatcher.py" in send
  175.             for receiver in self._live_receivers(sender)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\dispatch\dispatcher.py" in <listcomp>
  175.             for receiver in self._live_receivers(sender)

File "C:\xampp\htdocs\python\projects\tanariver\user_details\models.py" in create_user_profile
  32.         Profile.objects.create(user=instance)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\models\manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\models\query.py" in create
  413.         obj.save(force_insert=True, using=self.db)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\models\base.py" in save
  718.                        force_update=force_update, update_fields=update_fields)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\models\base.py" in save_base
  748.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\models\base.py" in _save_table
  831.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\models\base.py" in _do_insert
  869.                                using=using, raw=raw)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\models\manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\models\query.py" in _insert
  1136.         return query.get_compiler(using=using).execute_sql(return_id)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\models\sql\compiler.py" in execute_sql
  1289.                 cursor.execute(sql, params)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\backends\utils.py" in execute
  100.             return super().execute(sql, params)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\backends\utils.py" in execute
  68.         return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\backends\utils.py" in _execute_with_wrappers
  77.         return executor(sql, params, many, context)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\backends\utils.py" in _execute
  85.                 return self.cursor.execute(sql, params)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\utils.py" in __exit__
  89.                 raise dj_exc_value.with_traceback(traceback) from exc_value

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\backends\utils.py" in _execute
  85.                 return self.cursor.execute(sql, params)

File "C:\xampp\htdocs\python\envs\tanariver\lib\site-packages\django\db\backends\sqlite3\base.py" in execute
  296.         return Database.Cursor.execute(self, query, params)

Exception Type: IntegrityError at /admin/auth/user/add/
Exception Value: UNIQUE constraint failed: user_details_profile.phone

What am I missing?

It looks like the error you're getting has to do with the phone number field that you've declared as unique=True . Are you trying to add a user and giving that user the same phone number as a user that is already in the database?

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    try:
        instance.profile.save()
    except ObjectDoesNotExist:
        Profile.objects.create(user=instance)

Think about it: everytime you create and save a User entry on db, this code creates and saves a Profile entry on the db and links to it. Now, the only information you are providing for the creation of the profile entry is a user object it is related to.

When you create the first user, the corresponding profile entry has only the user field populated, all the other are blank/null - even phone . If you leave it as is and then create another user, it's profile will be created with an empty string as phone too; then you have a Unique constraint fail.

Posible solutions: avoid required fields in cases like this, provide meaningful defaults for non-null fields where appropriate, pass unique values for unique fields during object creation , do validation!, foresee and catch exceptions whenever it makes sense, respect model constraints when writing methods that create entries...

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    try:
        instance.profile.save()
    except ObjectDoesNotExist:
        phone = meaningful_phone_defaut_or_passed_argument
        # (...) other defaults
        Profile.objects.create(user=instance, phone=phone, )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM