web-dev-qa-db-ja.com

Djangoユーザープロファイルの編集

フロントで「プロフィールを編集」フォームを作成しようとしています。私のフォーム(100%確実ではありません)は、現在のユーザーを見つけてプロファイルを更新するのではなく、ユーザーを作成しようとします。それが問題だと思います。ここで多くの質問をチェックしましたが、十分に明確なものはありませんでした。編集しようとしているフィールドは、電子メール、姓、名です。 (また、私はウダを追加したいと思います

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)
13
manosim

あなたはとても近いです。フォームをインスタンス化するときは、変更する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

17
patsweet

または、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'

ここで、models.pyのMyProfileに次のようなものがあります。

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'),
....

残りはDjango楽しいです!基本的なCRUDタスクにできる場合は、何かカスタムを実行する必要がない限り、少ないコードを書くことをお勧めします。クラスベースのビュー。

さらに詳しく知りたい場合は、こちらをご覧ください クラスベースビューのDjangoドキュメント

5
KhoPhi