Django allauth 自定义登录表单未呈现自定义用户模型中的所有字段

Posted

技术标签:

【中文标题】Django allauth 自定义登录表单未呈现自定义用户模型中的所有字段【英文标题】:Django allauth custom login form not rendering all fields in custom user model 【发布时间】:2016-09-22 18:48:37 【问题描述】:

我正在尝试实现包含自定义用户模型的登录。是否可以从allauth.account.forms.LoginForm 继承并在自定义登录表单中添加自定义字段?

想法是通过覆盖在登录时为用户分配一个角色 login() 方法。

我已关注allauth configuration,并在 settings.py 中使用以下代码提到了用于登录的表单

AUTH_USER_MODEL = 'core.User'
ACCOUNT_SIGNUP_FORM_CLASS = 'core.forms.SignupForm'
ACCOUNT_FORMS = 'login': 'core.forms.CoreLoginForm'

除了django.contrib.auth.backends.ModelBackendallauth.account.auth_backends.AuthenticationBackend 之外,我没有使用任何身份验证后端。自定义注册对我来说工作正常,没有任何问题。但自定义登录表单并未呈现用户模型中的所有字段。 Allauth LoginForm 根据SO Post 中接受的答案继承,并在自定义登录表单中添加了一个选择字段。

from allauth.account.forms import LoginForm
class CoreLoginForm(LoginForm):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(CoreLoginForm, self).__init__(*args, **kwargs)
    role = forms.ChoiceField(widget=forms.Select(), choices=User.roles, initial=User.roles[0])

./manage.py runserver 上显示Module "core.forms" does not define a "SignupForm" class。我已经在 core.forms 和signup will work if CoreLoginForm is inherited from forms.Form instead of LoginForm 中定义了一个 SignupForm。所以如果我这样做了

class CoreLoginForm(forms.Form):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request', None)
        super(CoreLoginForm, self).__init__(*args, **kwargs)

    role = forms.ChoiceField(widget=forms.Select(), choices=User.roles, initial=User.roles[0])

我可以将自定义登录表单呈现到 html 页面。但这里的问题是我必须重新定义类中的每个方法,包括authenticate()perform_login() 等。这最终将复制整个 LoginForm 并将其粘贴到应用程序的 forms.py 中。我不想这样做,因为我认为这违反了 DRY 原则。有没有一种简单的方法可以将自定义字段添加到自定义登录表单并覆盖 login() 方法?

TIA

【问题讨论】:

【参考方案1】:

可能你已经解决了你的问题,但我会把这个解决方案留给像我这样在这个问题上花费超过 10 分钟的其他人:)

我找到了一种向 Allauth 登录表单添加字段的简单方法:

正如你所做的那样 - 添加到 settings.py :

ACCOUNT_FORMS = 'login': 'core.forms.CoreLoginForm'

然后在您的 forms.py 中添加:

from django import forms
from allauth.account.forms import LoginForm

class CoreLoginForm(LoginForm):

    def __init__(self, *args, **kwargs):
        super(CoreLoginForm, self).__init__(*args, **kwargs)
        ## here i add the new fields that i need
        self.fields["new-field"] = forms.CharField(label='Some label', max_length=100)

【讨论】:

有几种方法可以做到这一点,但我觉得这是最 Python/Django 的方式。解决和发布的好工作/赞成票值得。

以上是关于Django allauth 自定义登录表单未呈现自定义用户模型中的所有字段的主要内容,如果未能解决你的问题,请参考以下文章

Django Allauth 自定义登录模板不起作用

使用 django-allauth 启用 oauth 登录,但使用自定义提供程序

Django Allauth 自定义登录不显示错误

使用 django-allauth 实现 Ajax 请求/响应

覆盖 django-allauth 表单域

站点包中缺少 Django-allauth 模板