Django Редактировать профиль пользователя


Я пытаюсь создать форму "Редактировать профиль" в интерфейсе. Что происходит, так это то, что моя форма(я не уверен на 100%) пытается создать пользователя вместо того, чтобы найти текущего пользователя и обновить его профиль. Так что я думаю, что это проблема. Проверил здесь много вопросов, но ни один не был достаточно ясен. Поля, которые я пытаюсь редактировать, - это электронная почта, имя и фамилия. (Также я хотел бы добавить uda

Forms.py

class UpdateProfile(forms.ModelForm):
    username = forms.CharField(required=True)
    email = forms.EmailField(required=True)
    first_name = forms.CharField(required=False)
    last_name = forms.CharField(required=False)

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

    def clean_email(self):
        username = self.cleaned_data.get('username')
        email = self.cleaned_data.get('email')

        if email and User.objects.filter(email=email).exclude(username=username).count():
            raise forms.ValidationError('This email address is already in use. Please supply a different email address.')
        return email

    def save(self, commit=True):
        user = super(RegistrationForm, self).save(commit=False)
        user.email = self.cleaned_data['email']

        if commit:
            user.save()

        return user

Views.py

def update_profile(request):
    args = {}

    if request.method == 'POST':
        form = UpdateProfile(request.POST)
        form.actual_user = request.user
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('update_profile_success'))
    else:
        form = UpdateProfile()

    args['form'] = form
    return render(request, 'registration/update_profile.html', args)
2 13

2 ответа:

Вы очень близки. При создании экземпляра формы необходимо передать изменяемый объект User в качестве аргумента instance.

Из документов:

Подкласс ModelForm может принимать существующий экземпляр модели в качестве аргумент ключевого слова instance; если он указан, save () обновит этот экземпляр.

В вашем коде это будет выглядеть так:

form = UpdateProfile(request.POST, instance=request.user)
if form.is_valid():
    ...

Вы можете проверить дополнительную информацию здесь: https://docs.djangoproject.com/en/1.6/topics/forms/modelforms/#the-save-method

Или если вы хотите перейти к классовому представлению, используя UpdateView, вы можете сделать что-то подобное в views.py:

class UpdateProfile(UpdateView):
    model = MyProfile
    fields = ['first_name', 'last_name', 'image', 'url', 'biography', '...'] # Keep listing whatever fields 
    # the combined UserProfile and User exposes.
    template_name = 'user_update.html'
    slug_field = 'username'
    slug_url_kwarg = 'slug'

Где у вас есть что-то вроде этого для MyProfile в models.py:

class MyProfile(AbstractUser):
    image = models.ImageField(upload_to='uploads/profile/')
    url = models.URLField()
    biography = models.CharField(max_length=1000)

И ваш urls.py вот так (предполагая, что вы используете django allauth и хотите соблюдать соглашение об url):

....
url(r'^accounts/update/(?P<slug>[\-\w]+)/$', views.UpdateProfile.as_view(), name='update_user'),
....

Остальное-Джанго веселый! Я рекомендую вам писать меньше кода, если вы могли бы для основных задач CRUD, если только это действительно не нужно, чтобы сделать что-то обычное, из которых даже вы все еще можете уйти, расширив представления на основе классов.

И если вы хотите узнать больше, смотрите здесь: Django Docs on Class Based Views