Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

ERRORS: inside.UserProfile.user: (fields.E301) Field defines a relation with the model 'auth.User', which has been swapped out

I am a beginner in Django.
I am trying to build an app with user authentication. However I want extra fields like country and phone number, and I don’t want any username field (I want the phone number to act as the username), so I built a custom user class.
There are questions that have already been asked that have the same error, but they are not exactly relevant to my use case and the solutions don’t work for me.

models.py:

from django.db import models
from django.contrib.auth.models import User
from django.contrib.auth.models import AbstractBaseUser
from django.conf import settings

from django_countries.fields import CountryField

# Create your models here.

class UserProfile(AbstractBaseUser):

    user = models.OneToOneField(User, on_delete = models.DO_NOTHING)

    phone_number = models.CharField(max_length = 16, unique = True, blank = False, null = False)
    country = CountryField()
    uid = models.UUIDField(
        default = None,
        blank = True,
        null = True,
        unique = True,
    )
    USERNAME_FIELD = "uid"
    REQUIRED_FIELDS = ['phone_number', 'country']

forms.py:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import UserProfile

from django_countries.fields import CountryField


# Create your forms here..

class NewUserForm(UserCreationForm):
    phone_number = forms.RegexField(max_length = 16, regex = r'^\+?1?\d{9,15}$')
    country = CountryField()
    
    class Meta:
        model = UserProfile
        fields = ("phone_number", "country", "password1", "password2")
        
    def save(self, commit = True):
        user = super(NewUserForm, self).save(commit = False)
        user.phone_number = self.cleaned_data['phone_number']
        user.username = user.phone_number
        user.country = self.cleaned_data['country']
        if commit:
            user.save()
        return user

settings.py:

"""
Django settings for app project.

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

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

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

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


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

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-pu46*rr%pr(^utidu^bob6o#f*s4w5ig#$fmc$f@ga45+p2wzc'

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

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'inside.apps.InsideConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'crispy_forms',
    'phonenumber_field',
]

AUTH_USER_MODEL = 'inside.UserProfile'

CRISPY_TEMPLATE_PACK = 'bootstrap4'

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 = 'app.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 = 'app.wsgi.application'


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

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}


# Password validation
# https://docs.djangoproject.com/en/4.0/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/4.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Kolkata'

USE_I18N = True

USE_TZ = True


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

STATIC_URL = 'static/'

# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

Django throws this error:

Watching for file changes with StatReloader
Performing system checks...

Exception in thread django-main-thread:
Traceback (most recent call last):
  File "C:\Users\Kanav\AppData\Local\Programs\Python\Python39\lib\threading.py", line 973, in _bootstrap_inner
    self.run()
  File "C:\Users\Kanav\AppData\Local\Programs\Python\Python39\lib\threading.py", line 910, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\Kanav\AppData\Local\Programs\Python\Python39\lib\site-packages\django\utils\autoreload.py", line 64, in wrapper
    fn(*args, **kwargs)
  File "C:\Users\Kanav\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\management\commands\runserver.py", line 124, in inner_run
    self.check(display_num_errors=True)
  File "C:\Users\Kanav\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\management\base.py", line 488, in check
    raise SystemCheckError(msg)
django.core.management.base.SystemCheckError: SystemCheckError: System check identified some issues:

ERRORS:
inside.UserProfile.user: (fields.E301) Field defines a relation with the model 'auth.User', which has been swapped out.
        HINT: Update the relation to point at 'settings.AUTH_USER_MODEL'.

System check identified 1 issue (0 silenced).

>Solution :

You are defining a relationship to the default User Model, which you are not using anymore as you have created a custom user model. Remove the one_to_one_field to avoid this error
And to further errors you have to create a custom manager

from django.db import models
from django.contrib.auth.models import User
from django.contrib.auth.models import AbstractBaseUser
from django.conf import settings

from django_countries.fields import CountryField

# Create your models here.

class UserProfile(AbstractBaseUser):
    # Remove this as you no longer using the default User Model.
    # user = models.OneToOneField(User, on_delete = models.DO_NOTHING)
    phone_number = models.CharField(max_length = 16, unique = True, blank = False, null = False)
    country = CountryField()
    # As you are using UID as your username field 
    # it is not safe to make it blank and null true 
    uid = models.UUIDField(
        default = None,
        blank = True,
        null = True,
        unique = True,
    )
    USERNAME_FIELD = "uid"
    REQUIRED_FIELDS = ['phone_number', 'country']
    # Create your custom user manager 
    objects = YOUR_CUSTOM_USER_MANAGER()

Note: As you are using uid as your username field, you have to write a custom authentication backend so that you can use the phone number to authenticate the user, otherwise you have to use the phone number as a username field if you don’t want to create a custom authentication backend.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading