2

ユーザーが自分のプロファイルを変更できるように「ユーザーのプロファイルを更新する」ページを作成したいので、次のモデルを考え出します。

class Profile(models.Model):
    user = models.OneToOneField(User)

    nick_name = models.CharField(blank=True,max_length=100)
    school = models.CharField(blank=True,max_length=100)
    motto = models.CharField(blank=True,max_length=100)

class ProfileForm(ModelForm):
    class Meta:
        model = Profile

そして私の見解は次のように設計されています:

@login_required
def update_profile_view(request):
    if request.method == 'POST':
        user = request.user
        try:
            profile = user.get_profile()
        except Exception:
            profile = Profile.objects.create(user=user)
        form = ProfileForm(request.POST)
        if form.is_valid():
            cd = form.cleaned_data
            profile.nick_name = cd['nick_name']
            profile.school = cd['school']
            profile.motto = cd['motto']
            profile.save()
            return HttpResponseRedirect('/main_page/')
    else:
        form = ProfileForm()
    return render(request, 'update_profile.html', {'form':form})

ユーザーとプロファイルの関係は明らかに 1 対 1 であり、要求があれば現在のユーザーを特定できます。したがって、フォームのユーザー フィールドに入力する必要はありません。残念ながら、これは「form.is_valid()」テストに合格できませんでした。また、「is_valid」が呼び出される前にフォームを変更するのは難しいようです。簡単にするために、私は独自のフォーム クラスを作成したくありません。また、カスタマイズされたフォーム検証も作成したくありません。問題を解決する他の方法はありますか?

4

3 に答える 3

3

ビューを大幅に簡素化できます。

@login_required
def update_profile_view(request):
    try:
        profile = Profile.objects.get(user=request.user)
    except Profile.DoesNotExist:
        profile = None

    form = ProfileForm(request.POST or None, instance=profile)

    if request.method == 'POST':            
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/main_page/')
    return render(request, 'update_profile.html', {'form':form})

あなたがやっているように手動でフィールドを割り当てる必要はありません。Django ORM は、挿入と更新を自動的に行う方法を知っています。したがって、ProfileForm に Profile のインスタンスを渡すだけで、更新を実行することがわかります。プロファイルのインスタンスがない場合は、挿入が行われます。

ここで、ユーザーの割り当てを UI で透過的にしたい場合はuser、フォームからフィールドを除外して自分で割り当てる必要があります。これを行うには、いくつかの方法があります。

reverseハードコーディングされたパスがないように、リダイレクトを活用することもお勧めします。

于 2012-08-17T13:36:52.043 に答える
3

基本的に 2 つの選択肢があります。

1 ProfileForm の変更:

    class ProfileForm(ModelForm):
        class Meta:
            model = Profileclass
            exclude = ('user',)

2 この行を次のように変更します。

form = ProfileForm(request.POST, instance=profile)
if form.is_valid():
    updated_profile = form.save()
于 2012-08-17T13:39:04.870 に答える
0

フォームの init メソッドでユーザー フィールドの値を不要に設定する (self.fields['user'].required = False) か、モデルでユーザーを編集不可に設定する (editable=False) ことができます。

ビュー メソッドで、profile = form.save(commit=False) を呼び出し、次に profile.user = your_user および profile.save() を実行します。

ModelForm がこれを行うため、クリーンアップされたデータを手動でプロファイルに適用する必要はありません。

于 2012-08-17T13:35:33.920 に答える