web-dev-qa-db-fra.com

référence paresseux: ne fournit pas l'utilisateur modèle?

J'utilise actuellement Django 1.11 et Python 3.6. J'essaie de créer un modèle d'utilisateur personnalisé avec une nouvelle application qui s'authentifie avec LDAP, mais le message d'erreur suivant s'affiche.

    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'.

Paramètres.py Applications installées, Auth Backends et Modèle Auth_User:

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)

Ci-dessous mon 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"
5
student101

Pour moi aidé divisé sur deux migration 

  1. créer une nouvelle table (sans connexion entre les nouvelles et les anciennes tables et sans AUTH_USER_MODEL = 'accounts.User'
  2. ajoutez AUTH_USER_MODEL à settings.py et d'autres connexions avec une nouvelle table

Mais cela fonctionne pour les bases de données dev/production si vous souhaitez appliquer des migrations à partir de tests initiaux ou une autre création à partir de bases de données originales, vous devez "compacter vos migrations". Pour moi, c’était les prochaines étapes:

  1. Faire un dump d'une base de données (dans mon cas, par sqldump)
  2. Base de données de nettoyage (en particulier la table Django_migrations)
  3. Supprimer toutes les migrations de votre projet
  4. Exécuter manage.py makemigrations
  5. Ajoutez une migration qui ajoute toutes les insertions de données de vos anciennes migrations
  6. Exécuter manage.py migrate
  7. Supprimez la table Django_migrations dans votre vidage (peut-être une autre table Django_*
  8. Restaurer votre base de données à partir d'un cliché
4

Cela est dû au fait que votre settings.AUTH_USER_MODEL a été remplacé par un modèle inexistant lors du calcul des migrations.

Un moyen un peu compliqué de résoudre ce problème sans perte de données, si vous effectuez une migration d'auth.User vers custom.User consiste à ajouter un modèle minimal "virtuel" (base de données et état séparés) (c'est-à-dire, uniquement l'ID dans le champ, pour autoriser les clés étrangères) en fonction du nouveau modèle Utilisateur dans la migration initiale, donc les migrations futures ont cette référence:

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
3
AKX

Apparemment, rien n’était incorrect avec le code, j’ai juste dû abandonner toutes mes tables d’utilisateur, exécuter makemigration et migrer.

0
student101

AVERTISSEMENT: cela détruira vos tables et entrées utilisateur/groupe/authentification actuelles connectées avec le modèle utilisateur

En fait, dans Django 1.9+ cela suffit:

  • supprimez toutes les tables auth_* et Django_admin_log à l'aide de l'instruction suivante: 

DROP TABLE Django_admin_log, auth_group, auth_group_permissions, auth_permission, auth_user, auth_user_groups, auth_user_user_permissions CASCADE;

  • supprimer toutes les migrations connectées avec les applications Django_admin et auth avec:

DELETE FROM Django_migrations WHERE app='admin' or app='auth';

  • Puis lancez simplement:

./manage.py migrate

0
lechup

Ce:

Cela est dû au fait que votre paramètre.AUTH_USER_MODEL a été remplacé par un modèle inexistant lors du calcul des migrations.

... mentionné par @AKX in leur réponse m'a donné une idée qui a fonctionné.

J'ai fait ce qui suit:

  1. Faites tout pour mettre votre modèle User personnalisé en place. Définissez AUTH_USER_MODEL dans settings.py et mettez à jour toutes les utilisations de Django.contrib.auth.models.User avec votre modèle utilisateur personnalisé.
  2. Exécuter python manage.py makemigrations
  3. Annuler l'étape 1
  4. Exécuter python manage.py migrate
  5. Refaire l'étape 1
0
daka