AUTH_USER_MODEL
错误。密码仍无法通过表单保存用户创建。
我正在使用Django 1.5来使用新的用户覆盖/扩展功能,而且我无法通过我的注册表单注册新用户 - 只能通过管理员注册。通过注册表注册时,我收到以下错误:
Manager isn't available; User has been swapped for 'poker.PokerUser'
models.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)
PokerUserForm
型号:
class PokerUserForm(UserCreationForm):
class Meta:
model = PokerUser
fields = ('username','password1','password2','email','user_type','token','username1','username2','username3','username4','username5',)
我尝试更改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
我的AUTH_USER_MODEL
设置在我的settings.py
中,如此:
AUTH_USER_MODEL = 'poker.PokerUser'
我们去了 - 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:
According to the docs,必须重新创建UserCreationForm
以用于自定义用户类。
我覆盖了整个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
这可以解决此错误:
The Manager isn't available; User has been swapped for 'poker.PokerUser'
现在,用户已创建但无法登录。当我检查管理员中的用户时,除了密码之外,所有信息似乎都是正确的。在管理员中手动添加密码似乎无法正常工作。不过,通过管理员添加用户也能正常工作。
编辑2:
我仍无法登录通过注册表单创建的任何AbstractUser模型。我完全覆盖了UserCreationForm
,如上所述,我无法实施
get_user_model()
出现此错误:
AUTH_USER_MODEL refers to model 'poker.PokerUser' that has not been installed
get_user_model()
的Django代码是:
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
由于我在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
然而,实现仍然无法正常工作。
如果您已经读过这篇文章了,谢谢!
EDIT3:
AUTH_USER_MODEL refers to model 'poker.PokerUser' that has not been installed
已得到修复。我意外地在UserCreationForm
而不是poker.models
中重新创建了registration.forms
,所以当我运行get_user_model()
分配给poker.PokerUser
时,它无法解析因为它已经在那个地方了。
现在唯一的问题是,在创建新用户时,他们的密码将无法保存。我通过在此处放置打印语句将其缩小为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
print password1
中的print password1
和clean_password2
语句显示纯文本密码,但print self.cleaned_data["password1"]
方法中的save
为空。为什么我的表单数据没有传递给save方法?
TL; DR AbstractUser
模型创建在管理员和注册表单中都有效,但只有通过管理员创建的用户才能登录。通过注册表单创建的用户无法登录,似乎没有密码保存 - 所有其他信息都保存正确。
答案 0 :(得分:14)
好的,这里有三个问题,所以我打算解决所有这些问题,因为我很确定前两个问题会出现给其他人。
Manager isn't available; User has been swapped for 'poker.PokerUser'
这是因为使用但未重新创建UserCreationForm
。在1.5中使用自定义模型时,某些模型表单可以开箱即用,但必须重新创建。有关文档,请参阅here。
The Manager isn't available; User has been swapped for 'poker.PokerUser'
我在AUTH_USER_MODEL = 'poker.PokerUser'
设置settings.py
时,我从get_user_model()
位置拨打了poker.models
。您必须从其他位置致电get_user_model()
。将表单移至registration.forms
并从那里调用get_user_model()
可以正常工作。
这对我来说只是一个脑屁。在我的UserRegistration
模型中,我正在操作表单中的各个字段。当我将这些字段传递回UserCreationForm
save()
方法时,我没有传递密码字段。 Woops!
答案 1 :(得分:11)
我遇到过这几次。这一直是一个导入问题。假设我们有core / models.py实现自定义用户并从另一个文件中导入符号(比如Else):
from Something import Else
class CustomUser(AbstractBaseUser):
pass
然后我们有另一个使用CustomUser的文件,并且还定义了Else。我们称之为/ models.py:
from core.models import CustomUser
class Else(models.Model):
pass
class AnotherClass(models.model):
user = models.ForeignKey(CustomUser)
当core / models.py导入Else时,它会计算某些/ models.py并运行到AnotherClass定义中。 AnotherClass使用CustomUser,但还没有安装CustomUser,因为我们正在创建它。因此,它会抛出此错误。
我通过保持核心/ models.py独立来解决这个问题。它不会从我的其他应用程序导入太多。
答案 2 :(得分:2)
在我的案例更新中,meta中适当的app_label解决了这个问题
class APPUser(AbstractUser):
password = models.TextField(blank=True)
class Meta:
app_label = 'app_auth'
db_table = "app_user"
答案 3 :(得分:0)
如果您忘记在设置中注册应用,则可能会发生这种情况。在您的settings.py文件中,在INSTALLED_APPS列表中添加您的应用名称。我希望这会有所帮助。
例如,如果您的应用程序名称为“用户”,则它看起来像这样:
INSTALLED_APPS = [
......
'users'
]
答案 4 :(得分:0)
就我而言,我覆盖了内置的 User 模型并将导致此问题的类抽象化。因此,在元类中更改 abstract=False 解决了该问题。
class User(AbstractBaseUser, PermissionMixin):
email = models.EmailField(max_length=255)
class Meta:
abstract = False