Python AUTH_USER_MODEL 指的是模型 .. 尚未安装和创建 AbstractUser 模型无法登录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14699598/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:11:56  来源:igfitidea点击:

AUTH_USER_MODEL refers to model .. that has not been installed and created AbstractUser models not able to login

pythondjangodjango-1.5

提问by Dan Hoerst

AUTH_USER_MODELerror solved in EDIT3. Passwords still will not save on user creation via form.

AUTH_USER_MODEL错误在 EDIT3 中解决。密码仍然不会通过表单保存用户创建。

I'm using Django 1.5 playing around with the new user override/extension features, and I am not able to register new users via my registration form - only via the Admin. When registering via the registration form, I get the following error:

我正在使用 Django 1.5 来尝试新的用户覆盖/扩展功能,但我无法通过我的注册表单注册新用户 - 只能通过管理员。通过注册表进行注册时,出现以下错误:

Manager isn't available; User has been swapped for 'poker.PokerUser'

Manager isn't available; User has been swapped for 'poker.PokerUser'

models.py:

模型.py:

class PokerUser(AbstractUser):
    poker_relate = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True)
    token = models.EmailField()
    USER_CHOICES = (
        ('1', 'Staker'),
        ('2', 'Horse')
    )
    user_type = models.CharField(choices=USER_CHOICES, max_length=10)
    username1 = models.CharField(null=True, blank=True, max_length=40)
    username2 = models.CharField(null=True, blank=True, max_length=40)
    username3 = models.CharField(null=True, blank=True, max_length=40)
    username4 = models.CharField(null=True, blank=True, max_length=40)
    username5 = models.CharField(null=True, blank=True, max_length=40)

PokerUserFormmodel:

PokerUserForm模型:

class PokerUserForm(UserCreationForm):
    class Meta:
        model = PokerUser
        fields = ('username','password1','password2','email','user_type','token','username1','username2','username3','username4','username5',)

I've attempted to change the model in the PokerUserFormmodel to use get_user_model()instead of explicitly defining the model by setting model = get_user_model()instead of model = PokerUserbut then I receive the following error:

我试图将模型中的PokerUserForm模型更改为使用get_user_model()而不是通过设置model = get_user_model()而不是显式定义模型,model = PokerUser但随后我收到以下错误:

django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'poker.PokerUser' that has not been installed

My AUTH_USER_MODELis setup in my settings.pylike so:

AUTH_USER_MODEL的设置settings.py是这样的:

AUTH_USER_MODEL = 'poker.PokerUser'

AUTH_USER_MODEL = 'poker.PokerUser'

On we go - my Registration view in views.py:

我们继续 - 我的注册视图views.py

def UserRegistration(request):
    player = PokerUser()

    if request.method == 'POST':
        form = PokerUserForm(request.POST, instance=player)
        if form.is_valid():
            player.email_address = form.cleaned_data['email']
            player.user_type = form.cleaned_data['user_type']
            # if player is staker, token is their own email. otherwise their token is their staker's email and
            # their relation is their staker
            if player.user_type == '1' or player.user_type == 'staker':
                player.token = player.email_address
            else:
                player.token = form.cleaned_data['token']
                staker = PokerUser.objects.get(email=player.token)
                player.poker_relate = staker
            player.save()
            return HttpResponseRedirect('/')
    else:
        form = PokerUserForm()
    initialData = {'form': form}
    csrfContext = RequestContext(request, initialData)
    return render_to_response('registration/register.html', csrfContext)

EDIT1:

编辑1:

According to the docs, the UserCreationFormmust be recreated for use with custom user classes.

根据 docsUserCreationForm必须重新创建用于自定义用户类。

I overrode the entire UserCreationFormas follows:

我覆盖了整个UserCreationForm如下:

class UserCreationForm(forms.ModelForm):
    """
    A form that creates a user, with no privileges, from the given username and
    password.
    """
    error_messages = {
        'duplicate_username': _("A user with that username already exists."),
        'password_mismatch': _("The two password fields didn't match."),
        }
    username = forms.RegexField(label=_("Username"), max_length=30,
        regex=r'^[\w.@+-]+$',
        help_text=_("Required. 30 characters or fewer. Letters, digits and "
                    "@/./+/-/_ only."),
        error_messages={
            'invalid': _("This value may contain only letters, numbers and "
                         "@/./+/-/_ characters.")})
    password1 = forms.CharField(label=_("Password"),
        widget=forms.PasswordInput)
    password2 = forms.CharField(label=_("Password confirmation"),
        widget=forms.PasswordInput,
        help_text=_("Enter the same password as above, for verification."))

    class Meta:
        model = PokerUser
        fields = ('username','password1','password2','email','user_type','token','username1','username2','username3','username4','username5',)

    def clean_username(self):
        # Since User.username is unique, this check is redundant,
        # but it sets a nicer error message than the ORM. See #13147.
        username = self.cleaned_data["username"]
        try:
            PokerUser.objects.get(username=username)
        except PokerUser.DoesNotExist:
            return username
        raise forms.ValidationError(self.error_messages['duplicate_username'])

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError(
                self.error_messages['password_mismatch'])
        return password2

    def save(self, commit=True):
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

And this was able to resolve this error:

这能够解决此错误:

The Manager isn't available; User has been swapped for 'poker.PokerUser'

The Manager isn't available; User has been swapped for 'poker.PokerUser'

Now, the users get created but are not able to log in. When I check the users in the admin, all of the information seems to be correct except for the password. Adding a password manually in the admin does not seem to work correctly. Still, adding users via the admin work correctly.

现在,用户已创建但无法登录。当我检查管理员中的用户时,除了密码之外,所有信息似乎都是正确的。在管理员中手动添加密码似乎无法正常工作。尽管如此,通过管理员添加用户工作正常。

EDIT 2:

编辑2:

I'm still unable to login as any of my AbstractUser models created via the registration form. I have completely overridden the UserCreationFormas outlined above, and am unable to implement get_user_model()with this error:

我仍然无法以通过注册表创建的任何 AbstractUser 模型登录。我已经完全覆盖了UserCreationForm上面概述的内容,并且无法get_user_model()使用此错误实现 :

AUTH_USER_MODEL refers to model 'poker.PokerUser' that has not been installed

AUTH_USER_MODEL refers to model 'poker.PokerUser' that has not been installed

The Django code for get_user_model()is:

Django 代码get_user_model()是:

 def get_user_model():
    "Return the User model that is active in this project"
    from django.conf import settings
    from django.db.models import get_model

    try:
        app_label, model_name = settings.AUTH_USER_MODEL.split('.')
    except ValueError:
        raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'")
    user_model = get_model(app_label, model_name)
    if user_model is None:
        raise ImproperlyConfigured("AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL)
    return user_model

Since I have AUTH_USER_MODEL = 'poker.PokerUser'setup in my settings.py, this should work. I've verified this through the Django console:

由于我已经AUTH_USER_MODEL = 'poker.PokerUser'在我的settings.py. 我已经通过 Django 控制台验证了这一点:

>>> from django.contrib.auth import get_user_model
>>> settings.AUTH_USER_MODEL
Out[14]: 'poker.PokerUser'
>>> from django.db.models import get_model
>>> app_label, model_name = settings.AUTH_USER_MODEL.split('.')
>>> user_model = get_model(app_label, model_name)
>>> user_model
Out[18]: poker.models.PokerUser

However the implementation still does not work correctly.

然而,实现仍然不能正常工作。

If you've read this far, thanks!

如果你读到这里,谢谢!

EDIT3:

编辑3:

AUTH_USER_MODEL refers to model 'poker.PokerUser' that has not been installedhas been fixed. I accidentally had the UserCreationFormthat I recreated in poker.modelsinstead of registration.forms, so when I ran get_user_model()that was assigned to poker.PokerUser, it couldn't resolve since it was already in that location.

AUTH_USER_MODEL refers to model 'poker.PokerUser' that has not been installed已修复。我不小心使用了UserCreationForm重新创建的poker.models而不是registration.forms,所以当我运行get_user_model()分配给 的 时poker.PokerUser,它无法解析,因为它已经在那个位置。

Now the only issue left is that when creating new users, their passwords will not save. I've narrowed it down to a single method in the UserCreationFormby placing print statements here:

现在剩下的唯一问题是,在创建新用户时,他们的密码不会保存。我UserCreationForm通过在此处放置打印语句将其范围缩小到单个方法:

def clean_password2(self):
    password1 = self.cleaned_data.get("password1")
    print password1
    password2 = self.cleaned_data.get("password2")
    print password2
    if password1 and password2 and password1 != password2:
        raise forms.ValidationError(
            self.error_messages['password_mismatch'])
    print password2
    return password2

def save(self, commit=True):
    user = super(UserCreationForm, self).save(commit=False)
    user.set_password(self.cleaned_data["password1"])
    print self.cleaned_data["password1"]
    if commit:
        user.save()
    return user

The print password1and print password1statements in clean_password2display the plain text password, but print self.cleaned_data["password1"]in the savemethod is blank. Why is my form data not being passed to the save method?

print password1print password1在报表clean_password2显示的明文密码,但print self.cleaned_data["password1"]save方法是空白。为什么我的表单数据没有传递给 save 方法?

TL;DRAbstractUsermodel creation is working in both Admin and via registration form, but only the users created via Admin are able to login. The users created via the registration form are unable to log in and seem to be saved without a password - all other information is saved correctly.

TL;DRAbstractUser模型创建在 Admin 和通过注册表均可使用,但只有通过 Admin 创建的用户才能登录。通过注册表创建的用户无法登录,并且似乎没有密码即可保存 - 所有其他信息均已正确保存。

采纳答案by Dan Hoerst

Ok there were three issues here for me, so I'm going to address all of them since I am pretty sure the first two will come up for someone else.

好吧,这里有三个问题对我来说,所以我将解决所有这些问题,因为我很确定前两个会为其他人提出。

  • Manager isn't available; User has been swapped for 'poker.PokerUser'
  • Manager isn't available; User has been swapped for 'poker.PokerUser'

This was due to using but not recreating the UserCreationForm. When using custom models in 1.5, some model forms are available out of the box but this one must be recreated. See herefor the docs.

这是由于使用而不是重新创建UserCreationForm. 在 1.5 中使用自定义模型时,一些模型表单是开箱即用的,但必须重新创建这个表单。有关文档,请参见此处

  • The Manager isn't available; User has been swapped for 'poker.PokerUser'
  • The Manager isn't available; User has been swapped for 'poker.PokerUser'

While I had AUTH_USER_MODEL = 'poker.PokerUser'set in my settings.py, I was calling get_user_model()from the poker.modelslocation. You must call get_user_model()from a different location. Moving my form to registration.formsand calling get_user_model()from there worked correctly.

当我在我的 中AUTH_USER_MODEL = 'poker.PokerUser'设置时settings.py,我正在get_user_model()从该poker.models位置呼叫。您必须get_user_model()从不同的位置拨打电话。将我的表单移到那里registration.formsget_user_model()从那里调用工作正常。

  • New users not saving
  • 新用户不保存

This was just a brain fart on my end. In my UserRegistrationmodel I was manipulating various fields from the form. When I passed those fields back to UserCreationFormfor the save()method, I was not passing the password fields with it. Woops!

这对我来说只是一个脑放屁。在我的UserRegistration模型中,我正在操纵表单中的各个字段。当我通过这些领域回UserCreationFormsave()方法,我没有通过密码字段它。哇!

回答by Rob Jones

I've run into this a few times. It's always been an import issue. Suppose we have core/models.py that implements a custom user and imports a symbol from another file (say Else):

我已经遇到过几次了。一直是进口问题。假设我们有 core/models.py 实现自定义用户并从另一个文件导入符号(比如 Else):

from Something import Else

class CustomUser(AbstractBaseUser):
    pass

And then we have another file that uses CustomUser and also defines Else. Let's call this something/models.py:

然后我们有另一个使用 CustomUser 并定义 Else 的文件。让我们称它为 something/models.py:

from core.models import CustomUser

class Else(models.Model):
    pass

class AnotherClass(models.model):
    user = models.ForeignKey(CustomUser)

When core/models.py goes to import Else, it evaluates something/models.py and runs into the AnotherClass definition. AnotherClass uses CustomUser, but CustomUser hasn't been installed yet because we're in the process of creating it. So, it throws this error.

当 core/models.py 导入 Else 时,它​​会评估 something/models.py 并运行到 AnotherClass 定义中。AnotherClass 使用 CustomUser,但尚未安装 CustomUser,因为我们正在创建它。所以,它会抛出这个错误。

I've solved this problem by keeping my core/models.py standalone. It doesn't import much from my other apps.

我通过保持我的 core/models.py 独立解决了这个问题。它不会从我的其他应用程序中导入太多内容。

回答by naren

In my case updating, proper app_label in meta solved this issue

在我的情况下更新,元中适当的 app_label 解决了这个问题

class APPUser(AbstractUser):
   password = models.TextField(blank=True)

   class Meta:
     app_label = 'app_auth'
     db_table = "app_user"

回答by Reticent

It can happen if you forget to register your app in settings. In your settings.py file add the name of your app in the list of INSTALLED_APPS. I hope this helps.

如果您忘记在设置中注册您的应用程序,就会发生这种情况。在您的 settings.py 文件中,在 INSTALLED_APPS 列表中添加您的应用程序名称。我希望这有帮助。

For instance, if your app name is 'users' it would look like this:

例如,如果您的应用程序名称是“users”,它将如下所示:

INSTALLED_APPS = [
  ......

  'users'
]