Django 2.2 Удаление любого пользователя в интерфейсе администратора вызывает эту ошибку - PullRequest
0 голосов
/ 09 мая 2020

Вот рассматриваемая ошибка:

IntegrityError в / admin / accounts / user /

Ошибка ограничения FOREIGN KEY

Я искал в другом месте и не смог найти простого решения. Я считаю, что эта ошибка связана с тем, что я использовал пользовательскую модель User, в которой я наследую от AbstractBaseUser, потому что я хочу, чтобы на моем веб-сайте не было имен пользователей, а вместо этого пользователи определялись в первую очередь по их электронной почте. Я нахожусь на начальном уровне для использования Django, а также всего, что связано с реляционными базами данных.

#src/accounts.models.py
from django.conf import settings
from django.db import models
from django.db.models.signals import pre_save, post_save
from django.contrib.auth.models import (
    AbstractBaseUser, BaseUserManager
)

from django.core.mail import send_mail
from django.template.loader import get_template


class UserManager(BaseUserManager):
    def create_user(self, email, full_name=None, password=None, is_active=True, is_staff=False, is_admin=False):
        if not email:
            raise ValueError("Users must have an email address")
        if not password:
            raise ValueError("Users must have a password")
        user_obj = self.model(
            email = self.normalize_email(email),
            full_name=full_name
        )
        user_obj.set_password(password) # change user password
        user_obj.staff = is_staff
        user_obj.admin = is_admin
        user_obj.is_active = is_active
        user_obj.save(using=self._db)
        return user_obj

    def create_staffuser(self, email,full_name=None, password=None):
        user = self.create_user(
                email,
                full_name=full_name,
                password=password,
                is_staff=True
        )
        return user

    def create_superuser(self, email, full_name=None, password=None):
        user = self.create_user(
                email,
                full_name=full_name,
                password=password,
                is_staff=True,
                is_admin=True
        )
        return user


class User(AbstractBaseUser):
    email       = models.EmailField(max_length=255, unique=True)
    full_name   = models.CharField(max_length=255, blank=True, null=True)
    is_active   = models.BooleanField(default=True) # can login 
    staff       = models.BooleanField(default=False) # staff user non superuser
    admin       = models.BooleanField(default=False) # superuser 
    timestamp   = models.DateTimeField(auto_now_add=True)

    USERNAME_FIELD = 'email' #username
    # USERNAME_FIELD and password are required by default
    REQUIRED_FIELDS = [] #['full_name'] #python manage.py createsuperuser

    objects = UserManager()

    def __str__(self):
        return self.email


class EmailActivation(models.Model):
   user            = models.ForeignKey(User, 
   blank=True,
   null=True, 
   on_delete=models.CASCADE
) # required on Django 2.0+ deletes child objects on_delete
  #the error must be caused by this
    email           = models.EmailField()
    key             = models.CharField(max_length=120, blank=True, null=True)
    activated       = models.BooleanField(default=False)
    forced_expired  = models.BooleanField(default=False)
    expires         = models.IntegerField(default=7) # 7 Days
    timestamp       = models.DateTimeField(auto_now_add=True)
    update          = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.email

    def regenerate(self):
        self.key = None
        self.save()
        if self.key is not None:
            return True
        return False

    def send_activation(self):
        if not self.activated and not self.forced_expired:
            if self.key:
                base_url = getattr(settings, 'BASE_URL', '<my-domain>')
                key_path = self.key # use reverse
                path = "{base}{path}".format(base=base_url, path=key_path)
                context = {
                    'path': path,
                    'email': self.email
                }
                txt_ = get_template("registration/emails/verify.txt").render(context)
                html_ = get_template("registration/emails/verify.html").render(context)
                subject = '1-Click Email Verification'
                from_email = settings.DEFAULT_FROM_EMAIL
                recipient_list = [self.email]
                sent_mail = send_mail(
                            subject,
                            txt_,
                            from_email,
                            recipient_list,
                            html_message=html_,
                            fail_silently=False,
                    )
                return sent_mail
        return False



def pre_save_email_activation(sender, instance, *args, **kwargs):
    if not instance.activated and not instance.forced_expired:
        if not instance.key:
            instance.key = unique_key_generator(instance)

pre_save.connect(pre_save_email_activation, sender=EmailActivation)


def post_save_user_create_reciever(sender, instance, created, *args, **kwargs):
    if created:
        obj = EmailActivation.objects.create(user=instance, email=instance.email)
        obj.send_activation()

post_save.connect(post_save_user_create_reciever, sender=User)

class GuestEmail(models.Model):
    email       = models.EmailField()
    active      = models.BooleanField(default=True)
    update      = models.DateTimeField(auto_now=True)
    timestamp   = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.email

РЕДАКТИРОВАТЬ: В соответствии с просьбой Тома Каррика, вот моя полная трассировка:

> Environment:
>
>
>Request Method: POST
>Request URL: http://127.0.0.1:8000/admin/accounts/user/

>Django Version: 2.2.12
>Python Version: 3.6.9
>Installed Applications:
>['django.contrib.admin',
> 'django.contrib.auth',
> 'django.contrib.contenttypes',
> 'django.contrib.sessions',
> 'django.contrib.messages',
> 'django.contrib.staticfiles',
> 'storages',
> 'accounts',
> 'addresses',
> 'analytics',
> 'billing',
> 'carts',
> 'marketing',
> 'orders',
> 'products',
> 'search',
> 'tags']
>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 "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute
>  84.                 return self.cursor.execute(sql, params)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py" in execute
>  383.         return Database.Cursor.execute(self, query, params)
>
>The above exception (FOREIGN KEY constraint failed) was the direct >cause of the following exception:
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
>  34.             response = get_response(request)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
>  115.                 response = >self.process_exception_by_middleware(e, request)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
>  113.                 response = wrapped_callback(request, >*callback_args, **callback_kwargs)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/contrib/admin/options.py" in wrapper
>  606.                 return self.admin_site.admin_view(view)(*args, >**kwargs)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapped_view
>  142.                     response = view_func(request, *args, >**kwargs)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
>  44.         response = view_func(request, *args, **kwargs)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/contrib/admin/sites.py" in inner
>  223.             return view(request, *args, **kwargs)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapper
>  45.         return bound_method(*args, **kwargs)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapped_view
>  142.                     response = view_func(request, *args, >**kwargs)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/contrib/admin/options.py" in changelist_view
>  1727.                 response = self.response_action(request, >queryset=cl.get_queryset(request))
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/contrib/admin/options.py" in response_action
>  1397.             response = func(self, request, queryset)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/contrib/admin/actions.py" in delete_selected
>  40.             modeladmin.delete_queryset(request, queryset)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/contrib/admin/options.py" in delete_queryset
>  1098.         queryset.delete()
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/models/query.py" in delete
>  711.         deleted, _rows_count = collector.delete()
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/models/deletion.py" in delete
>  312.                 count = query.delete_batch(pk_list, self.using)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/models/sql/subqueries.py" in delete_batch
>  41.             num_deleted += >self.do_query(self.get_meta().db_table, self.where, using=using)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/models/sql/subqueries.py" in do_query
>  24.         cursor = self.get_compiler(using).execute_sql(CURSOR)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in execute_sql
>  1140.             cursor.execute(sql, params)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
>  99.             return super().execute(sql, params)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
>  67.         return self._execute_with_wrappers(sql, params, >many=False, executor=self._execute)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute_with_wrappers
>  76.         return executor(sql, params, many, context)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute
>  84.                 return self.cursor.execute(sql, params)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/utils.py" in __exit__
>  89.                 raise dj_exc_value.with_traceback(traceback) from >exc_value
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute
>  84.                 return self.cursor.execute(sql, params)
>
>File "/home/ray/Dev/rxvenv/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py" in execute
>  383.         return Database.Cursor.execute(self, query, params)
>
>Exception Type: IntegrityError at /admin/accounts/user/
>Exception Value: FOREIGN KEY constraint failed
>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...