Редактирование сохраненного профиля пользователя в django - PullRequest
0 голосов
/ 11 июля 2019

Я создал регистрационную форму с моделью пользователя django с добавлением дополнительного поля verify_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 голосов
/ 11 июля 2019

Вы сами реализуете много логики, которую ModelForm должен обработать. Одна из основных целей ModelForm - создание и редактирование объектов модели без большого количества шаблонной логики.

Непонятно, почему вы вообще используете вторую форму. Тем более, что вы не делаете этого и не делаете с ним много. Так что, возможно, имеет смысл отбросить эту форму.

Ваш EditProfileForm содержит супер-вызов с классом, который не является суперклассом этого класса, вы должны использовать super(ModelForm, self) вместо super(UserForm, self).

class EditProfileForm(forms.ModelForm):

    # ...

    def clean(self):
        cleaned_data = super(<b>ModelForm</b>, self).clean()
        # ...
        return cleaned_data

Основная проблема заключается в том, что вы инициализируете форму с помощью:

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

, поскольку user не имеет confirm_pwd поля или атрибута или свойства.

Кроме того, модель User не сохраняет необработанные пароли. Эти пароли хэшируются, чтобы хакер не смог проверить пароли, если им удастся получить доступ к базе данных.

Вы можете реализовать свой вид с помощью:

from django.contrib.auth.decorators import <b>login_required</b>
from django.shortcuts import <b>redirect</b>

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

Вероятно, было бы лучше пропатчить __init__ вашего EditProfileForm, поскольку теперь он будет инициализировать поле пароля с помощью хешированной версии пароля. Таким образом, он отличается от введенного пароля и, кроме того, он предоставляет некоторые данные в базе данных, которые, вероятно, следует хранить в безопасности.

0 голосов
/ 11 июля 2019

В вашем views.py вы получаете user из request.user и пытаетесь присвоить новое значение confirm_pwd. Тем не менее, user не имеет confirm_pwd. То, что user является пользователем Django, а не вашим UserProfileInfo. Удаление строки ниже на вашем views.py должно работать. Кроме того, вам не нужно сохранять подтверждение пароля, это должно быть сделано только для проверки.

# to be removed
user.confirm_pwd = request.POST['confirm_pwd']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...