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

cut*_*eth 1 python forms django django-allauth

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

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

我已经按照allauth的配置进行了配置,并通过以下代码提到了在settings.py中用于登录的形式

AUTH_USER_MODEL = 'core.User'
ACCOUNT_SIGNUP_FORM_CLASS = 'core.forms.SignupForm'
ACCOUNT_FORMS = {'login': 'core.forms.CoreLoginForm'}
Run Code Online (Sandbox Code Playgroud)

django.contrib.auth.backends.ModelBackend和外,我没有使用任何身份验证后端allauth.account.auth_backends.AuthenticationBackend。自定义注册对我来说工作正常,没有任何问题。但是自定义loginform不会呈现用户模型中的所有字段。根据此SO Post中接受的答案继承了Allauth LoginForm,并将choicefield添加到自定义登录表单中。

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])
Run Code Online (Sandbox Code Playgroud)

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

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])
Run Code Online (Sandbox Code Playgroud)

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

TIA

小智 5

也许您已经解决了您的问题,但我会将这个解决方案留给像我这样花费超过10分钟的其他人来解决:)

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

完成后,添加到settings.py:

ACCOUNT_FORMS = {'login': 'core.forms.CoreLoginForm'}
Run Code Online (Sandbox Code Playgroud)

然后在您的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)
Run Code Online (Sandbox Code Playgroud)