python - 即使在 forms.py 中 UserRegistrationForm 的 Meta 类中使用 "exclude"变量后,password1、password2 的字段也会显示(在注册页面)

标签 python django django-registration

在 Django Web 应用程序的注册页面,我只想询问所需的用户名和电子邮件地址,系统将通过电子邮件将随机生成的密码发送到用户给定的 ID。我该怎么办?

我正在使用 django 2.2.2 和 python 3.7.3。我正在使用 Crispy_forms 来渲染表单。

相关 django 表单文档 here .

我已经在 UserRegisterForm 类的 Meta 类中使用了“排除”变量。查看代码以了解我所做的事情

forms.py文件中:

class UserRegisterForm(UserCreationForm):
    """
    Inheriting the UserCreationForm class to add some additional fields in
    the registration form because the #s of fields
    in the UserCreationForm class has less fields than required.
    We add email field in this extended class.
    """

    email = forms.EmailField()

    class Meta:
        model = User
        fields = ("username", "email")
        exclude = ("password1", "password2")

我的register.html模板文件:

{% extends "blog/base.html" %}
{% load i18n %}
{% load crispy_forms_tags %}

{% block content %}
  <div class="content-section">
    <form method="POST">
      {% csrf_token %}
      <fieldset class="form-group">
        <legend>
          Join here!
        </legend>
        {{ form|crispy }}
      </fieldset>
      <div>
        <button>Sign up!</button>
      </div>
    </form>
    <small class="text-muted">
      Already have an account? Sign in <a href="{% url "login" %}" class="ml-2">here</a>.
    </small>
  </div>
{% endblock content %}

我的views.py文件:

def register(request):
    """
    Triggered when AnonymousUser clicks on the 'Sign Up' button anywhere on the site

    The process:
    1. User visits registration page
    2. User enters his/her email only.
    3. System makes an account in the database & sends an email
       to that id with the password.
    4. User logs in the website using that password
    """
    if not request.user.is_authenticated:
        if request.method == "POST":
            request.POST = request.POST.copy() # To make the request.POST mutable
            request.POST['password1'] = get_random_alphanumeric_password(_max_len=8)
            request.POST['password2'] = request.POST['password1']
            form = UserRegisterForm(request.POST)

            if form.is_valid():
                form.save()
                # WORKS!
                messages.success(request, _(f"Account successfully created"))
                send_mail(subject=_(f"KBank - Password for {request.POST['username']}"),
                          message=_(f"Thanks for signing up at KBank. The password is {request.POST['password1']}"),
                          from_email=os.environ.get("EMAIL_USER"),
                          recipient_list=[f"{request.POST['email']}"],
                          )
                messages.info(request, _("Please check your email for password & log in using that"))
                return redirect('login')
        else:
            form = UserRegisterForm()
        return render(request, "users/register.html", {"form": form})
    else:
        return redirect("site-home")

错误是要求输入密码 1 和密码 2 的两个字段仍然显示在我的注册页面上。

enter image description here

最佳答案

fieldsexclude 属性适用于从模型创建的字段。 password1和password2字段不是来自模型,它们是直接在UserCreationForm上定义的额外字段。

您可以重写 init 方法以从表单中删除这些方法,但我不确定您为什么要这样做。我也不明白为什么,如果你不想显示表单,你仍然想改变 request.POST 来传递它们。实际上你应该只使用标准的 ModelForm,然后在保存时设置随 secret 码。所以:

class UserRegisterForm(forms.ModelForm):

    class Meta:
        model = User
        fields = ("username", "email")

def register(request):
    if not request.user.is_authenticated:
        if request.method == "POST":
            form = UserRegisterForm(request.POST)

            if form.is_valid():
                user = form.save(commit=False)
                new_password = get_random_alphanumeric_password(_max_len=8)
                user.set_password(new_password)
                user.save()
                messages.success(request, _(f"Account successfully created"))
                send_mail(subject=_(f"KBank - Password for {user.username}"),
                      message=_(f"Thanks for signing up at KBank. The password is {new_password}"),
                      from_email=os.environ.get("EMAIL_USER"),
                      recipient_list=[user.email],
                )
        ...

(请注意,您应该在电子邮件中使用来自用户对象的数据,而不是原始 POST 数据。)

关于python - 即使在 forms.py 中 UserRegistrationForm 的 Meta 类中使用 "exclude"变量后,password1、password2 的字段也会显示(在注册页面),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56592537/

相关文章:

python - 需要降级 pandas 版本,但出现 "ModuleNotFoundError"错误

python - 在 seaborn stripplot 中为点添加标签

python - 使用 float ('nan' ) 来表示缺失值 - 安全吗?

python - django rest auth 返回 AnonymousUser

Django 1.4.1 错误报告不给我发送电子邮件

python - Django - 身份验证,使用电子邮件确认注册

python - 使用 pyparsing 连接三元运算符

python - 如何在Django Form的clean()方法中获取auto_id?

python - 向 django 注册表单添加额外字段

Django-Registration: 电子邮件作为用户名