在Django中编辑已保存的用户个人资料

时间:2019-07-11 07:31:18

标签: django

我使用django用户模型创建了一个注册表单,并添加了一个额外的字段Confirm_pwd。我创建了一个编辑页面来编辑特定用户的详细信息。编辑后,我需要在个人资料页面中显示个人资料详细信息。我也创建了个人资料页面。但是仅在用户注册或登录时才显示。编辑详细信息后单击“保存”按钮,它会重定向到个人资料页面。目前,个人资料页面没有显示详细信息。这是我的代码

models.py

from django.db import models
from django.contrib.auth.models import User


class UserProfileInfo(models.Model):
    user = models.OneToOneField(User,on_delete=models.CASCADE)

    def __str__(self):
        return self.user.username

forms.py

from django import forms
from django.forms import ModelForm
from .models import UserProfileInfo
from django.contrib.auth.models import User
class EditProfileForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
confirm_pwd = forms.CharField(widget=forms.PasswordInput())
class Meta():
    model = User
    fields = ['first_name','last_name','username','email','password']
    help_texts={
        'username': None
    }
def clean(self):
    cleaned_data = super(EditProfileForm, self).clean()
    password = cleaned_data.get("password")
    confirm_password = cleaned_data.get("confirm_pwd")
    print(confirm_password)

    if password != confirm_password:
        print("yes")
        raise forms.ValidationError(
            "password and confirm_password does not match"
        )  

views.py

from django.shortcuts import render
from django.http import HttpResponseRedirect, HttpResponse
from .models import UserProfileInfo
from django.contrib.auth.models import User
from .forms import UserForm,UserProfileInfoForm,GithubInfo,EditProfileForm
from django.contrib.auth import authenticate, login, logout
from django.urls import reverse
@login_required
def edit_profile(request):
    if request.method == 'POST':
        form = EditProfileForm(request.POST, instance=request.user)
        if form.is_valid():
            user = form.save(commit=False)
            user.set_password(form.cleaned_data['password'])
            user.save()
            return HttpResponseRedirect(reverse('signupapp:profile'))
    else:
        form=EditProfileForm(instance=request.user)
    return render(request, "signupapp/edit_profile.html", {'form':form })

edit_profile.html

<form method="POST" action="" class="" >
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Save</button>
</form>

profile.html

{% if user.is_authenticated %}
<h1>Welcome!</h1>
<h3>Firstname: {{ user.first_name }}</h3>
<h3>Lastname: {{ user.last_name }}</h3>
<h3>Username: {{ user.username }}</h3>
<h3>Email: {{ user.email }}</h3>
<a href="{% url 'signupapp:edit' %}"><input type="button" value="Edit"/></a>
<a href="{% url 'signupapp:delete' request.user.id %}"><input type="button" value="Delete"/></a><br>
<br>
{% else %}
<h3>Register or Login if you'd like to</h3>
{% endif %}

当我在服务器上运行此代码时,个人资料页面不会显示用户详细信息。

我该如何做到这一点。 预先感谢。

2 个答案:

答案 0 :(得分:0)

在您的views.py中,您从user获取request.user,并尝试为confirm_pwd分配一个新值。但是,user没有confirm_pwduser是Django用户,而不是您的UserProfileInfo。通过删除views.py下方的行,它应该可以工作。此外,您无需保存密码确认,仅用于检查目的。

# to be removed
user.confirm_pwd = request.POST['confirm_pwd']

答案 1 :(得分:0)

您自己实现了ModelForm应该处理的许多逻辑。 ModelForm的主要目的之一就是创建和编辑模型对象而无需大量样板逻辑。

目前尚不清楚为什么要使用第二种形式。尤其是因为您不渲染它,也不对其进行任何处理。因此,删除该表格可能更有意义。

您的EditProfileForm确实包含对不是该类超类的类的超级调用,您应该使用super(ModelForm, self)而不是 super(UserForm, self)

class EditProfileForm(forms.ModelForm):

    # ...

    def clean(self):
        cleaned_data = super(ModelForm, self).clean()
        # ...
        return cleaned_data

主要问题是您使用以下方法初始化表单:

pform = UserProfileInfoForm(request.POST or None, initial={'confirm_pwd': user.confirm_pwd})

因为user没有confirm_pwd字段,属性或属性。

此外,User模型还保存原始密码。这些密码经过散列处理,以防止黑客在设法访问数据库时检查密码。

您可以通过以下方式实现视图:

from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect

@login_required
def edit_profile(request):
    if request.method == 'POST':
        form = EditProfileForm(request.POST, instance=request.user)
        if form.is_valid():
            user = form.save(commit=False)
            user.set_password(form.cleaned_data['password'])
            user.save()
            return redirect('signupapp:profile')
    else:
        form=EditProfileForm(instance=request.user)
    return render(request, "signupapp/edit_profile.html", {'form':form })

最好修补__init__中的EditProfileForm,因为现在它将使用密码的哈希版本来初始化密码字段。因此,这与输入的密码不同,此外,它还公开了数据库中应该安全保存的一些数据。