редактировать профиль пользователя в django без ввода пароля

здесь я пытаюсь разрешить пользователям вносить изменения в свой профиль. Существует модель под названием UserProfile, которая поддерживает отношения один к одному с самим пользователем django. Ниже приведен код в views.py

@login_required
def edit_profile(request):  
    if request.method == 'POST':
        profile = UserProfile.objects.get(user=request.user)
        profile_form = UserProfileForm(data=request.POST, instance=profile)

        if profile_form.is_valid():

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

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

            return HttpResponseRedirect("/me/login/")

        else:
            print user_form.errors, profile_form.errors
    else:
        user = request.user
        profile = UserProfile.objects.get(user=user)
        profile_form = UserProfileForm(initial={'website':profile.website,'address':profile.address, 'picture':profile.picture})

    return render(request, 'member/edit_profile.html', {'profile_form': profile_form})

Однако после того, как в шаблоне была нажата кнопка отправки, я получил сообщение об ошибке, в котором говорилось, что требуется пароль.

[27/Apr/2015 14:25:07] "GET /me/edit_profile2/ HTTP/1.1" 200 5080
<ul class="errorlist"><li>username<ul class="errorlist"><li>This field is required.</li></ul></li><li>password<ul class="errorlist"><li>This field is required.</li></ul></li></ul> 
[27/Apr/2015 14:25:16] "POST /me/edit_profile/ HTTP/1.1" 200 6384

Из кода я подумал, что UserProfile уже привязан к конкретному пользователю, и я разрешаю пользователям вносить изменения только в модель UserProfile, не касаясь модели User django auth. Интересно, зачем в этом случае все же нужны логин и пароль. Можно ли разрешить редактирование профиля пользователя без пароля пользователя?

Вот UserProfile, расширенный из модели User

class UserProfile(models.Model):
    # link user profile to the user models
    user = models.OneToOneField(User)

    website = models.URLField(blank=True)
    picture = models.ImageField(upload_to='avatar', blank=True)
    address = models.TextField(blank=True)

    @property
    def stats(self):
        """get statistics for this profile"""
        from tumboon.models import Donation
        return Donation.statistics.for_user(self)

    @property
    def amount_donated(self):
        __doc__ = """get the total amount donated """
        return self.stats['total_amount_donated']

    # Override the __unicode__ to return something meaningful
    def __unicode__(self):
        return self.user.username

class UserForm(forms.ModelForm):
    """Form for User Registration"""

    class Meta:
        model = User
        fields = ('username', 'email', 'password', 'first_name', 'last_name')
        widgets = {
            'username' : forms.TextInput(attrs = {'placeholder': 'Username'}),
            'email'    : forms.TextInput(attrs = {'placeholder': 'Email'}),
            'password'    : forms.TextInput(attrs = {'placeholder': 'Password'}),            
        }

class UserProfileForm(forms.ModelForm):
    """Form for UserProfile"""
    class Meta:
        model = UserProfile
        fields = ('website', 'picture', 'address')

И UserProfileForm в шаблоне находится здесь:

{% if user.is_authenticated %}
        <form id="user_profile" class="form-horizontal" method="POST" enctype="multipart/form-data" action="/me/edit_profile/"> 
            {% csrf_token %}
            <h3>User Info</h3>
            <hr />
            <div class="form-group">
                <label class="col-xs-2" for="{{ user_form.picture.id_for_label }}">Picture: </label>
                <div class="col-xs-10">
                    {{profile_form.picture|add_class:"form-control"}}
                </div>
            </div>
            <div class="form-group">
                <label class="col-xs-2" for="{{ user_form.website.id_for_label }}">Website: </label>
                <div class="col-xs-10">
                    {{profile_form.website|add_class:"form-control"}}
                </div>
            </div>
            <div class="form-group">
                <label class="col-xs-2" for="{{ user_form.address.id_for_label }}">Address: </label>
                <div class="col-xs-10">
                    {{profile_form.address|add_class:"form-control"}}</li>
                </div>
            </div>
            <input class="btn btn-default" type="submit" name="save_button" value="Save Profile">
        </form>
    {% endif %}

person Kann    schedule 27.04.2015    source источник
comment
Пожалуйста, опубликуйте свой UserProfileForm   -  person Reto Aebersold    schedule 27.04.2015
comment
Вы можете опубликовать класс Python UserProfileForm? Я просто вижу UserForm.   -  person Reto Aebersold    schedule 27.04.2015
comment
Привет, Aebersold, я только что добавил сюда UserProfileForm.   -  person Kann    schedule 27.04.2015
comment
Вы уверены, что ваша точка зрения верна? И что ваш URL-адрес попадает в правильное представление? Можете ли вы показать свое представление и свой urls.py?   -  person Daniel Roseman    schedule 27.04.2015
comment
У вас есть форма для основной модели пользователя на той же странице? Может быть, вы отправляете и то, и другое. В любом случае, вы используете неправильные теги шаблона в некоторых опубликованных вами HTML. Например, <label class="col-xs-2" for="{{ user_form.picture.id_for_label }}"> должно быть <label class="col-xs-2" for="{{ profile_form.picture.id_for_label }}">   -  person onyeka    schedule 27.04.2015
comment
@DanielRoseman Вы правы; на самом деле есть опечатка в urls.py, которая повредила метод POST, поскольку он как бы отправил данные формы в никуда. Я починил это сейчас. Спасибо, что указали на это.   -  person Kann    schedule 28.04.2015


Ответы (1)


Ваш класс UserForm расширяет класс Model.Form, который отображает поле пароля по мере необходимости, отсюда и проблема. Вместо этого используйте UserChangeForm:

from django.contrib.auth.forms import UserChangeForm

class UserForm(UserChangeForm):
    class Meta:
        model = User
        fields = ('username', 'email', 'first_name', 'last_name', 'is_super_admin')

Эта форма обрабатывает пароль должным образом.

person vladimir.gorea    schedule 12.02.2019
comment
Моя форма расширяет UserChangeForm, но у меня все еще есть эта проблема. Что я делаю неправильно? - person Dmitry Malugin; 19.03.2020