Python 创建帐户页面上的密码未正确保存到数据库

Python 创建帐户页面上的密码未正确保存到数据库,python,django,Python,Django,我有这张表格,几乎是直接从上面的第二个绿色框复制过来的: 表单正确显示,并按预期捕获错误(如“密码不匹配”),但当尝试使用刚刚创建的用户/密码登录时,它失败。我可以通过电子邮件重置密码,然后成功登录 为什么表单没有正确保存密码 (用户的“积极性”在这里重要吗?) (另外,我知道有一个auth表单已经完成了这个create-a-user-account-with-password-confirmation,但我没有看到它) views.py def create_user_account_suc

我有这张表格,几乎是直接从上面的第二个绿色框复制过来的:

表单正确显示,并按预期捕获错误(如“密码不匹配”),但当尝试使用刚刚创建的用户/密码登录时,它失败。我可以通过电子邮件重置密码,然后成功登录

为什么表单没有正确保存密码

(用户的“积极性”在这里重要吗?)

(另外,我知道有一个auth表单已经完成了这个create-a-user-account-with-password-confirmation,但我没有看到它)


views.py

def create_user_account_success(request):
    return  render_to_response("registration/create_account_success.html", RequestContext(request))

MIDDLE_YEAR_STR = str(DISCOVERED_MIN_YEAR + ((DISCOVERED_MAX_YEAR - DISCOVERED_MIN_YEAR) // 2))


def create_user_account(request):
    context = RequestContext(request)

    if(request.method == "POST"):
        #Form was filled. Process it.

        user_form = UserForm(data=request.POST)
        profile_form = UserProfileForm(data=request.POST)

        if(user_form.is_valid() and profile_form.is_valid()):

            #To get a form element, use either
            #print(request.POST["password1"])

            #or, *after* calling UserForm(data=request.POST) and then
            #user_form.is_valid():
            #print(user_form.cleaned_data["password1"])

            #commit
            user = user_form.save()


            user.set_password(user.password)
            user.save()

            profile = profile_form.save(commit=False)
            profile.user = user

            if("picture" in request.FILES):
                profile.picture = request.FILES["picture"]

            profile.save()

            return  redirect("create_account_success")

    else:
        #Not a POST. Form hasn't been filled. Get a blank form
        global  MIDDLE_YEAR_STR

        user_form = UserForm()
        profile_form = UserProfileForm(initial={
            "year_discovered": MIDDLE_YEAR_STR})

    context["user_form"] = user_form
    context["profile_form"] = profile_form

    #Render and display the form
    return  render_to_response("registration/create_account.html", context)
forms.py

from  django import forms
from  django.contrib.auth.models import User
from  .models import UserProfile, DISCOVERED_MIN_YEAR, DISCOVERED_MAX_YEAR

class UserForm(forms.ModelForm):
    password1 = forms.CharField(label="Password", widget=forms.PasswordInput())
    password2 = forms.CharField(label="Password confirmation", widget=forms.PasswordInput())

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

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password2"])
        if commit:
            user.save()
        return user

class UserProfileForm(forms.ModelForm):
    year_choices = ((x,str(x)) for x in range(DISCOVERED_MIN_YEAR, DISCOVERED_MAX_YEAR+1))
    #year_discovered = forms.ChoiceField(choices=year_choices)

    year_discovered = forms.IntegerField(required=False,
        min_value=DISCOVERED_MIN_YEAR, max_value=DISCOVERED_MAX_YEAR,
        widget=forms.Select(choices=year_choices))

    #year_discovered = forms.IntegerField(min_value=DISCOVERED_MIN_YEAR, max_value=DISCOVERED_MAX_YEAR)

    class Meta:
        model = UserProfile
        fields = ('year_discovered', 'profile_picture')
创建_account.html

{% extends "base.html" %}

{% block title %}Create account{% endblock %}

{% block content %}
  <h1>Billy Joel Album Browser: Create account</h1>

        {% if registration_was_successful %}
          <P>Success!</P>
        {% else %}


        <form id="user_form" method="post" action="{% url 'create_account' %}"
                enctype="multipart/form-data">

            {% csrf_token %}

            <!-- Display each form. The as_p method wraps each element in a paragraph
                 (<p>) element. This ensures each element appears on a new line,
                 making everything look neater. -->
            {{ user_form.as_p }}
            {{ profile_form.as_p }}

            <!-- Provide a button to click to submit the form. -->
            <input type="submit" name="submit" value="Register" />
        </form>
        {% endif %}
{% endblock %}
{%extends“base.html”%}
{%block title%}创建帐户{%endblock%}
{%block content%}
Billy Joel相册浏览器:创建帐户
{%如果注册成功{u%}

成功

{%else%} {%csrf_令牌%} {{user_form.as_p} {{profile_form.as_p} {%endif%} {%endblock%}
创建\u帐户\u success.html

{% extends "base.html" %}

{% block content %}

<H1>Welcome!</H1>

<P><a href="{% url 'login' %}">Login</A> to proceed.</P>

{% endblock %}
{%extends“base.html”%}
{%block content%}
欢迎

继续。

{%endblock%}
表单和视图之间的密码设置代码存在一些重复,这导致了您的问题

在表单的
save
方法中,正确调用
user.set_password()
将哈希密码设置到新创建的用户上。但是,您的视图再次调用
set\u password
:因此它所做的是获取已经散列的密码,再次散列,然后将双重散列的密码设置到用户身上。当然,当您登录时,密码不再匹配,因为它已被双重哈希


只需从您的视图中删除两行(
user.set_password
user.save
)即可。

。非常感谢。我最初是从[Tango With Django教程](www.tangowithdjango.com/book/chapters/login.html)创建视图的,该教程没有密码确认。然后我按照Django的指示添加了密码确认,但没有意识到冗余。
{% extends "base.html" %}

{% block content %}

<H1>Welcome!</H1>

<P><a href="{% url 'login' %}">Login</A> to proceed.</P>

{% endblock %}