ここでいくつかの問題があり、ドキュメントと SO を検索して、さらに混乱するようにしました。
主な問題:
私はviews.pyにロードするUserProfileFormを持っています:
from braces.views import LoginRequiredMixin, CsrfExemptMixin
class UpdateUserProfileView(LoginRequiredMixin, CsrfExemptMixin, UpdateView):
model = UserProfile
success_url = reverse_lazy('profile_update')
form_class = UserProfileForm
そして私のurls.pyで:
urlpatterns = patterns('',
url(r'^(?P<pk>\d+)/$', UpdateUserProfileView.as_view(), name='profile_update'),
)
としてログインするとuser_id 2
、自分のプロファイル/profile/2/
が に表示されますが、 キーを/profile/1/
入力すると、 のユーザー プロファイルを編集できますuser_id 1
。ここで私が間違っていることはありますか?アクセスを制限するにはどうすればよいですか? 代わりにテンプレートで行う必要がありますか? (私は以前に両方のユーザーとしてログインしました)
サブ問題:
ここで reverse_lazy が機能しないようで、このエラーが返されます:モデルに
Reverse for 'profile_update' with arguments '()' and keyword arguments '{}' not found.
a を追加get_absolute_url
し、メイン プロジェクトの URL からこの urls.py を呼び出しています。プロファイルを作成するための別のビューについて、保存時にフォームが重複キーを作成しないようにするためのベスト プラクティスは何ですか?
編集:
@mariodev の提案に基づいて、urls.py を書き直しました。
urlpatterns = patterns('',
url(r'^create/$', CreateUserProfileView.as_view(), name='profile_create'),
url(r'^view/$', UpdateUserProfileView.as_view(), name='profile_update'),
)
views.py に、新しいクラスを追加しました。
class GetProfileMixin(object):
def get_object(self):
profile = get_object_or_404(UserProfile, user=self.request.user)
if profile.user != self.request.user:
raise Http404
return profile
そして、以下を使用して UpdateUserProfileFormView を呼び出します。
class UpdateUserProfileView(LoginRequiredMixin, GetProfileMixin, UpdateView):
model = UserProfile
form_class = UserProfileForm
createview に再度アクセスすると、オブジェクトを再度保存するときに、userprofile テーブル内の URL とforeign_key の重複に関するいくつかの小さな問題が残りました。これはよくある問題だと思いますが、明らかな答えを見逃しています。
編集2:
以下を変更しました。
def form_valid(self, form):
try:
created = UserProfile.objects.get(user=self.request.user)
except UserProfile.DoesNotExist:
profile = form.save(commit=False)
profile.user = self.request.user
profile.save()
return super(CreateUserProfileView, self).form_valid(form)
return HttpResponseRedirect('/accounts/profile/')
最も洗練されたソリューションではありません。現在のプロファイルに値が含まれている場合でも、ユーザーは空のフォームを取得し、送信された場合はプロファイル ページにリダイレクトするだけです。