Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

lazy reference: doesn't provide model user?

Currently I'm using Django 1.11 and Python 3.6. I'm attempting to create a custom user model with a new application that authenticates with LDAP, but i'm greeted with the following error message.

    raise ValueError("\n".join(error.msg for error in errors))
ValueError: The field admin.LogEntry.user was declared with a lazy reference to 'accounts.user', but app 'accounts' doesn't provide model 'user'.

Settings.py Installed Apps, Auth Backends, and Auth_User Model:

INSTALLED_APPS = [
    'django_python3_ldap',
    'django_extensions',
    'django_filters',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'accounts',
]


AUTHENTICATION_BACKENDS = (
    'django_python3_ldap.auth.LDAPBackend',
    'django.contrib.auth.backends.ModelBackend',
)

AUTH_USER_MODEL = "accounts.User"

Admin.py:

from django.contrib import admin
from django.conf import settings
from .models import User

# Register your models here.
admin.site.register(User)

Below is my models.py:

from __future__ import unicode_literals
from django.utils import timezone
from django.contrib.auth.models import (AbstractBaseUser,PermissionsMixin)
from django.db import models
from django.forms import ModelForm


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    username = models.CharField(max_length=25, unique=True)
    first_name = models.CharField(max_length=40)
    last_name = models.CharField(max_length=140)
    date_joined = models.DateTimeField(default=timezone.now)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    facility = models.CharField(max_length=140)
    jobdescription = models.CharField(max_length=140)
    positiondescription = models.CharField(max_length=140)

    USERNAME_FIELD = "username"
like image 804
student101 Avatar asked Nov 01 '17 16:11

student101


4 Answers

This:

This is caused by your settings.AUTH_USER_MODEL having changed to a model that does not exist when migrations are being computed.

... mentioned by @AKX in their answer below gave me an idea which worked.

I did the following:

  1. Do everything to put your custom User model into place. Set AUTH_USER_MODEL in settings.py and update any uses of django.contrib.auth.models.User with your custom user model.
  2. Run python manage.py makemigrations
  3. Undo step 1
  4. Run python manage.py migrate
  5. Redo step 1
like image 104
daka Avatar answered Nov 05 '22 08:11

daka


For me helped split on two migration

  1. create new table (without connection between new and old tables and without AUTH_USER_MODEL = 'accounts.User')
  2. add AUTH_USER_MODEL to settings.py and other connections with new table

But it works for dev/production databases if you want to apply migrations from first in tests or another from scratch database creations you should "compact your migrations", for me it was next steps:

  1. Make a dump of a database (in my case by sqldump)
  2. Cleanup database (especially table django_migrations)
  3. Remove all migrations in your project
  4. Run manage.py makemigrations
  5. Add migration that adds all data inserts from your old migrations
  6. Run manage.py migrate
  7. Remove table django_migrations in your dump (maybe some other django_* tables )
  8. Restore your database from a dump
like image 33
Ryabchenko Alexander Avatar answered Nov 05 '22 07:11

Ryabchenko Alexander


This is caused by your settings.AUTH_USER_MODEL having changed to a model that does not exist when migrations are being computed.

A slightly hacky way to fix this without data loss, if you're migrating from auth.User to custom.User is to add a "virtual" (separate database and state) minimal model (that is, only the ID field, to allow for foreign keys) according to the new User model in the very initial migration, so future migrations have this reference:

operations=[
    migrations.SeparateDatabaseAndState(
        state_operations=[
            migrations.CreateModel(
                name="User",
                fields=[
                    (
                        "id",
                        models.AutoField(
                            auto_created=True,
                            primary_key=True,
                            serialize=False,
                            verbose_name="ID",
                        ),
                    )
                ],
                options={"db_table": "auth_user"},
                managers=[("objects", UserManager())],
            )
        ]
    ),
    # ... other migrations
like image 45
AKX Avatar answered Nov 05 '22 08:11

AKX


Warning: It will delete your whole database. If you have some important data then backup it by dumpdata and then restore it by loaddata. for more info check here (I am not sure about this).

It is very difficult to change AUTH_USER_MODEL in the middle of the project. See the note in the docs. Infect after you are done with your first migration of Django tables, you will face problems.

Idea is: You need to include your custom user model with its entry in setting.py (AUTH_USER_MODEL = [custom user model] ) in your first-ever migration (where django create its own table like auth_group, dajango_migrations etc... ) of Django project.

Warning: If you have started server then Django itself create database and then this will not work, so please do not start the server.

  • Delete dbsqlite3 database file, delete all your migrations files and its binary files (In app/migration/pycache ) except init file and comment out all your models and it's dependencies (like, you have used model in any form then comment it also).
  • Now uncomment only custom user model
  • add AUTH_USER_MODEL in setting.py (AUTH_USER_MODEL = [custom user model] )
  • and then run makemigrations and migrate. (this will create your all Django tables and your custom user model.)

It is done.

now you can start the server.

after that uncomment all other models and migrate them.

like image 4
Bhargav Prajapati Avatar answered Nov 05 '22 06:11

Bhargav Prajapati