如何扩展Django“登录”表单?

2024-06-16 14:11:17 发布

您现在位置:Python中文网/ 问答频道 /正文

所以,现在我正在做基本的登录。在urls.py中,我转到django contrib登录:

(r'^login/?$','django.contrib.auth.views.login',{'template_name':'login.html'}),

射向这里:

@csrf_protect
@never_cache
def login(request, template_name='registration/login.html',
          redirect_field_name=REDIRECT_FIELD_NAME,
          authentication_form=AuthenticationForm):

该视图使用AuthenticationForm表单模型:

class AuthenticationForm(forms.Form):
    """
    Base class for authenticating users. Extend this to get a form that accepts
    username/password logins.
    """
    username = forms.CharField(label=_("Username"), max_length=30)
    password = forms.CharField(label=_("Password"), widget=forms.PasswordInput)

所以…我的目标是更改用户名表单!把这个加到上面:widget = forms.TextInput(attrs={'placeholder': 'username'})。就这样。这就是我想添加到用户名输入框中的所有内容。但是,我不想更改实际的django forms.py文件,因为这是django contrib的一部分,更改该文件我感觉很糟糕。

我该怎么办?是否应创建扩展AuthenticationForm的窗体?如果是,如何导入?如何通过url.py将其作为参数传入?我不知道该怎么办。


Tags: djangonamepyform表单htmlusernamelogin
3条回答

下面是另一个解决方案,使用path而不是不推荐的url,创建页面和表单的自定义版本,以便在完成电子邮件中发送的链接后重置密码。我正在使用Django 2和Python 3。

在我的api应用程序文件夹中,我创建了一个包含三个文件的文件夹templates/account。

基本.html:

<!DOCTYPE html>
<html>
  <head>
    <title>{% block head_title %}{% endblock %}</title>
    {% block extra_head %}
    {% endblock %}
  </head>
  <body>
    {% block body %}
    {% block content %}
    {% endblock %}
    {% endblock %}
    {% block extra_body %}
    {% endblock %}
  </body>
</html>

密码重置完成.html:

{% extends "account/base.html" %}

{% block content %}

<h3>Password reset successful</h3>

<p>Your password has been changed. Please log in using the link below.</p>

<p><a href="/login/">Login</a></p>

{% endblock %}

密码重置确认.html:

{% extends 'account/base.html' %}

{% block content %}
  {% if validlink %}
    <h3>Enter your new password</h3>
    <form method="post">
      {% csrf_token %}
      {{ form.as_p }}
      <button type="submit">Change password</button>
    </form>
  {% else %}
    <p>
      The password reset link was invalid, possibly because it has already been used.
      Please request a new password reset.
    </p>
  {% endif %}
{% endblock %}

在我的api应用程序文件夹中,我为自定义表单创建了一个文件forms.py,它扩展了默认的SetPasswordForm表单。

forms.py格式:

from django import forms
from django.contrib.auth.forms import SetPasswordForm
from django.utils.translation import gettext, gettext_lazy as _
from django.contrib.auth import password_validation

class SetPasswordFormCustom(SetPasswordForm):
    new_password1 = forms.CharField(
        label=_("New password custom"),
        widget=forms.PasswordInput,
        strip=False,
    )
    new_password2 = forms.CharField(
        label=_("New password confirmation custom"),
        strip=False,
        widget=forms.PasswordInput,
        help_text=password_validation.password_validators_help_text_html(),
    )

最后是url.py:

# api/urls.py
from django.urls import include, path
from django.contrib.auth import views
from django.conf.urls import include, url
from django.views.generic.base import RedirectView
from .forms import SetPasswordFormCustom

urlpatterns = [
...
path('reset/<uidb64>/<token>/',
    views.PasswordResetConfirmView.as_view(template_name='account/password_reset_confirm.html',
    form_class=SetPasswordFormCustom),
    name='password_reset_confirm'),
path('reset/done/', views.PasswordResetCompleteView.as_view(template_name='account/password_reset_complete.html'), name='password_reset_complete'),

]

注意“from.forms import SetPasswordFormCustom”。这个。允许导入同一文件夹中的文件。

我之所以这么做,是因为我还没有在本地React frontend中使用reset password,所以我必须为这个函数使用Django模板。我希望能够重新设计它的风格,并有与我的应用程序尽可能适合的链接。但是这个方法通常应该允许您创建自己的Django auth表单的自定义版本。

您需要对AuthenticationForm类进行子类划分,然后需要更改urls.py

class MyAuthenticationForm(AuthenticationForm):
    # add your form widget here
    widget = .....

然后将这个类导入到urls.py文件中并更新调用

(r'^login/?$','django.contrib.auth.views.login',{'template_name':'login.html', 'authentication_form':MyAuthenticationForm}),

我太累了,无法在文档站点上查找链接来查看您需要使用的字段类型,但这应该可以帮助您在不必修改django forms.py的情况下开始使用,而您肯定会对更改django forms.py感到遗憾!

正如milkypostman所说,您需要创建auth.forms.AuthenticationForm的子类。

然后,可以使用django crispy表单将占位符放入所需的字段中。就这么简单:

(app/forms.py)

class LoginWithPlaceholder(AuthenticationForm):

    def __init__(self, *args, **kwargs):
        super(LoginWithPlaceholder, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_show_labels = False
        self.helper.layout = Layout(Div(Field('username', placeholder='username'), css_class="form-group"),
                                    Div(Field('password', placeholder='password'), css_class="form-group"),
                                    Div(Submit('submit', 'Log in')))

最后,不要忘记在模板中使用crispy标记:

<div class="col-sm-6 col-sm-offset-3">        
{% crispy form %}            
</div>

相关问题 更多 >