在django-allauth中使用自定义注册表单时,外键约束失败

问题描述 投票:0回答:1

我正在使用自定义用户模型,并且已将手机号码设置为我的标识符。该模型如下所示。

from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser
)

# Create your models here.

class UserManager(BaseUserManager):
    def create_user(self, mobile_number, password=None):
        """
        Creates and saves a User with the given email and password.
        """

        if not mobile_number:
            raise ValueError('Users must have an mobile number')



        user = self.model(
            mobile_number = mobile_number,

        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_staffuser(self, mobile_number, password):
        """
        Creates and saves a staff user with the given email and password.
        """
        user = self.create_user(
            mobile_number =  mobile_number,
            password=password,
        )
        user.staff = True
        user.save(using=self._db)
        return user

    def create_superuser(self, mobile_number,  password):
        """
        Creates and saves a superuser with the given email and password.
        """
        user = self.create_user(
            mobile_number = mobile_number,
            password=password,
        )
        user.staff = True
        user.admin = True
        user.save(using=self._db)
        return user




class User(AbstractBaseUser):
    email = models.EmailField(
        verbose_name='email address',
        max_length=255,

        blank=True,
        null=True,
    )

    mobile_number = models.CharField(max_length= 11,unique=True)
    active = models.BooleanField(default=True)
    staff = models.BooleanField(default=False) # a admin user; non super-user
    admin = models.BooleanField(default=False) # a superuser
    username = models.CharField(max_length=40, unique=True,blank=True,null=True)

    # notice the absence of a "Password field", that's built in.

    USERNAME_FIELD = 'mobile_number'
    REQUIRED_FIELDS = [] # Email & Password are required by default.


    objects = UserManager()

    def get_full_name(self):
        # The user is identified by their phone number
        return self.mobile_number

    def get_short_name(self):
        # The user is identified by their phone number
        return self.mobile_number

    def __str__(self):              # __unicode__ on Python 2
        return str(self.mobile_number)

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        return self.staff

    @property
    def is_admin(self):
        "Is the user a admin member?"
        return self.admin

    @property
    def is_active(self):
        "Is the user active?"
        return self.active



IntegrityError at /accounts/signup/
FOREIGN KEY constraint failed



Environment:


Request Method: POST
Request URL: http://localhost:8000/accounts/signup/

Django Version: 2.2.7
Python Version: 3.6.5
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sites',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework',
 'rest_framework.authtoken',
 'rest_auth',
 'rest_auth.registration',
 'allauth',
 'allauth.account',
 'core',
 'allauth.socialaccount']
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 "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute
  84.                 return self.cursor.execute(sql, params)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/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 "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
  34.             response = get_response(request)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  115.                 response = self.process_exception_by_middleware(e, request)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
  113.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/views/generic/base.py" in view
  71.             return self.dispatch(request, *args, **kwargs)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapper
  45.         return bound_method(*args, **kwargs)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/views/decorators/debug.py" in sensitive_post_parameters_wrapper
  76.             return view(request, *args, **kwargs)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/allauth/account/views.py" in dispatch
  215.         return super(SignupView, self).dispatch(request, *args, **kwargs)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/allauth/account/views.py" in dispatch
  81.                                             **kwargs)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/allauth/account/views.py" in dispatch
  193.                                                           **kwargs)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/views/generic/base.py" in dispatch
  97.         return handler(request, *args, **kwargs)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/allauth/account/views.py" in post
  104.             response = self.form_valid(form)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/allauth/account/views.py" in form_valid
  231.         self.user = form.save(self.request)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/allauth/account/forms.py" in save
  404.         adapter.save_user(request, user, self)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/allauth/account/adapter.py" in save_user
  243.             user.save()

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/contrib/auth/base_user.py" in save
  66.         super().save(*args, **kwargs)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/models/base.py" in save
  741.                        force_update=force_update, update_fields=update_fields)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/models/base.py" in save_base
  790.                 update_fields=update_fields, raw=raw, using=using,

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/dispatch/dispatcher.py" in send
  175.             for receiver in self._live_receivers(sender)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/dispatch/dispatcher.py" in <listcomp>
  175.             for receiver in self._live_receivers(sender)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/src/core/models.py" in create_auth_token
  171.         Token.objects.create(user=instance)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/models/manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/models/query.py" in create
  422.         obj.save(force_insert=True, using=self.db)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/rest_framework/authtoken/models.py" in save
  33.         return super().save(*args, **kwargs)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/models/base.py" in save
  741.                        force_update=force_update, update_fields=update_fields)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/models/base.py" in save_base
  779.                 force_update, using, update_fields,

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/models/base.py" in _save_table
  870.             result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/models/base.py" in _do_insert
  908.                                using=using, raw=raw)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/models/manager.py" in manager_method
  82.                 return getattr(self.get_queryset(), name)(*args, **kwargs)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/models/query.py" in _insert
  1186.         return query.get_compiler(using=using).execute_sql(return_id)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in execute_sql
  1335.                 cursor.execute(sql, params)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/backends/utils.py" in execute
  99.             return super().execute(sql, params)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/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 "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute_with_wrappers
  76.         return executor(sql, params, many, context)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute
  84.                 return self.cursor.execute(sql, params)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/utils.py" in __exit__
  89.                 raise dj_exc_value.with_traceback(traceback) from exc_value

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/lib/python3.6/site-packages/django/db/backends/utils.py" in _execute
  84.                 return self.cursor.execute(sql, params)

File "/Users/ammarkhan/Desktop/TheFoodApp/FoodApp/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 /accounts/signup/
Exception Value: FOREIGN KEY constraint failed

我正在使用allauth并覆盖了注册表单,以便在表单中包括手机号码字段,但是一旦我点击了注册按钮,就会收到以下错误消息。我有一个想法,可能是因为令牌,因为用户注册后不会自动创建令牌。

class SignupForm(forms.ModelForm):
    mobile_number = forms.CharField(max_length=11)
    class Meta:
        model = User
        fields = ['mobile_number'] 

    def signup(self, request, user):
        print("User is",user)
        user.mobile_number = self.cleaned_data['mobile_number']
        user.save()
        return user

我的最终目标是使用手机号码字段作为前端以及API调用中的登录名。

更新1:

Settings.py文件

"""
Django settings for foodapp project.

Generated by 'django-admin startproject' using Django 2.2.7.

For more information on this file, see
https://docs.djangoproject.com/en/2.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.2/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = ''

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
     'django.contrib.sites',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
    'rest_framework.authtoken',
    'rest_auth',
    'rest_auth.registration',
    'allauth',
    'allauth.account',
    'core',
     'allauth.socialaccount',
]

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',
]

ROOT_URLCONF = 'foodapp.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'foodapp.wsgi.application'


# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/

STATIC_URL = '/static/'



STATICFILES_DIRS = (
    os.path.join(BASE_DIR, "static"),

)

STATIC_ROOT = os.path.join(BASE_DIR, "live-static", "static-root")




MEDIA_URL = "/media/"

MEDIA_ROOT = os.path.join(BASE_DIR, "live-static", "media-root")

AUTHENTICATION_BACKENDS = (

    # Needed to login by username in Django admin, regardless of `allauth`
    'django.contrib.auth.backends.ModelBackend',

    # `allauth` specific authentication methods, such as login by e-mail
    'allauth.account.auth_backends.AuthenticationBackend',

)
SITE_ID = 1

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',  
    ],
}


# REST_AUTH_REGISTER_SERIALIZERS = {
#     'REGISTER_SERIALIZER': 'core.api.serializers.MyRegisterSerializer',
# }


AUTH_USER_MODEL = 'core.User'
ACCOUNT_SIGNUP_FORM_CLASS = 'core.forms.SignupForm'
ACCOUNT_USERNAME_REQUIRED = False

ACCOUNT_USER_MODEL_USERNAME_FIELD = 'mobile_number'
# REST_SESSION_LOGIN = True
# # EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# # ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_REQUIRED = False   
# ACCOUNT_USERNAME_REQUIRED = False
# ACCOUNT_EMAIL_VERIFICATION = 'optional'


# REST_AUTH_SERIALIZERS = {
#     'LOGIN_SERIALIZER': 'blog.serializers.LoginSerializer',
# }

# ACCOUNT_USER_MODEL_USERNAME_FIELD = None
# ACCOUNT_EMAIL_REQUIRED = False
# ACCOUNT_USERNAME_REQUIRED = False
# ACCOUNT_USER_MODEL_EMAIL_FIELD = 'mobile_number'
python django python-3.x django-rest-framework django-allauth
1个回答
0
投票

您是否在settings.py中定义了用户模型?

AUTH_USER_MODEL = 'myapp.MyUser'
© www.soinside.com 2019 - 2024. All rights reserved.