今回のテーマは「ユーザープロフィール画面を作成する」です。ユーザー情報に関する画面はログインユーザーしかアクセスできない仕様を想定しています。ここではログインユーザーのみアクセスできるビューについて解説していきます。
※本ページは「ユーザー登録画面を作成する」まで読まれた方を対象としています。そのためサンプルソースコードが省略されている場合があります。
LoginRequiredMixinとlogin_requiredデコレータ
Djangoにはログインユーザーしかアクセスできないする仕掛けとしてlogin_requiredデコレータとLoginRequiredMixinがあります。login_requiredデコレータは関数ベースビューに用います。LoginRequiredMixinはクラスベースビューで使用します。複数のクラスを継承する際にはLoginRequiredMixinは一番先に記載するように注意してください。login_requiredもしくはLoginRequiredMixinが付与されているビューにアクセスしようとするとログイン画面に飛ばされるようになっています。
LOGIN_URLについて
LoginRequiredMixinを継承したクラス(正確にはAccessMixin)を継承したクラスはlogin_urlを設定することが出来ます。これはログイン画面のURLです。もしこれが設定されていない場合はsettings.pyのLOGIN_URLが用いられます。デフォルトでは’/accounts/login/’です。
ちなみにlogin_requiredデコレータでは引数でlogin_urlを渡します。
ユーザープロフィール画面を作成する
まずはテンプレートを新規作成します。
templates/registration/profile.html
{% extends 'base/base.html' %}
{% block title %}ITについて切磋琢磨する掲示板 - {{ block.super }}{% endblock %}
{% block content %}
<div class="ui grid stackable">
<div class="eleven wide column">
<div class="ui breadcrumb">
<a href="{% url 'base:top' %}" class="section">TOP</a>
<i class="right angle icon divider"></i>
<a class="active section">ユーザー情報</a>
</div>
<div class="ui segment">
<div class="content">
<div class="header"><h3>ユーザー情報</h3></div>
<div class="ui divided bulleted list">
<div class="item">ログインID:{{user.username}}</div>
<div class="item">E-mail:{% if user.email %}{{user.email}}{% else %}未設定{% endif %}</div>
<div class="item">名字:{% if user.last_name %}{{user.last_name}}{% else %}未設定{% endif %}</div>
<div class="item">名前:{% if user.first_name %}{{user.first_name}}{% else %}未設定{% endif %}</div>
</div>
</div>
</div>
<a class="ui button" href="">登録情報変更</a>
<a class="ui button" href="">パスワード変更</a>
</div>
{% include 'base/sidebar.html' %}
</div>
{% endblock %}
次にビューを作成していきます。
accounts/views.py(一部抜粋)
from django.contrib.auth.mixins import LoginRequiredMixin
class UserProfileView(LoginRequiredMixin, TemplateView):
template_name = 'registration/profile.html'
def get_queryset(self):
return User.objects.get(id=self.request.user.id)
先程説明したLoginRequiredMixinが使われていますね。ここではlogin_urlは設定していないので、もしログインしない状態で、このページにアクセスすると/accounts/login/にアクセスしようとしてエラーとなります。(現段階ではログイン画面作成していないため)
では作成したプロフィール画面にアクセスするためのURLを設定しましょう。
accounts/urls.py(一部抜粋)
urlpatterns = [
# path('', include('django.contrib.auth.urls')),
path('create/', views.UserCreateView.as_view(), name="create"),
+ path('profile/', views.UserProfileView.as_view(), name="profile"),
]
ヘッダーのURL修正
画面のヘッダーの「ユーザーの情報」にURLを設定しましょう。
{% load static %}
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<meta http-equiv="content-language" content="ja">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
{% block meta_tag %}{% endblock %}
<link href="{% static 'css/semantic.css' %}" rel="stylesheet">
{% block css %}{% endblock %}
<title>
{% block title %}IT学習ちゃんねる{% endblock %}
</title>
</head>
<body>
<div class="ui stackable inverted menu">
<a href="{% url 'base:top' %}" class="header item">
IT学習ちゃんねる
</a>
<a href="{% url 'base:about' %}" class="item">
このサイトはなに?
</a>
<a class="item" href="{% url 'thread:create_topic' %}">
トピック作成
</a>
<div class="right menu">
{% if user.is_authenticated %}
- <a class="item" href="">ユーザー情報</a>
+ <a class="item" href="{% url 'accounts:profile' %}">ユーザー情報</a>
<a class="item" href="">ログアウト</a>
{% else %}
<a class="item" href="">ログイン</a>
<a class="item" href="{% url 'accounts:create' %}">ユーザー登録</a>
{% endif %}
</div>
</div>
<div class="ui container" style="min-height:100vh;">
{% block content %}
{% endblock %}
</div>
<div class="ui inverted stackable footer segment">
<div class="ui container center aligned">
<div class="ui horizontal inverted small divided link list">
<a href="{% url 'base:top' %}" class="item">© 2019 IT学習ちゃんねる(仮)</a>
<a href="{% url 'base:terms' %}" class="item">利用規約</a>
<a href="{% url 'base:policy' %}" class="item">プライバシーポリシー</a>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.1.1.js"></script>
<script type="text/javascript" src="{% static 'js/semantic.js' %}"></script>
{% block js %}{% endblock %}
</body>
ユーザー登録後の遷移先を変更する
現在はユーザー登録後にトップページに遷移するようになっています。これを登録後にユーザープロフィール画面に遷移するように変更しましょう。
accounts/views.py(一部抜粋)
class UserCreateView(FormView):
form_class = UserCreationForm
template_name = 'registration/create.html'
- success_url = reverse_lazy('base:top')
+ success_url = reverse_lazy('accounts:profile')
def form_valid(self, form):
print(self.request.POST['next'])
if self.request.POST['next'] == 'back':
return render(self.request, 'registration/create.html', {'form': form})
elif self.request.POST['next'] == 'confirm':
return render(self.request, 'registration/create_confirm.html', {'form': form})
elif self.request.POST['next'] == 'regist':
form.save()
# 認証
user = authenticate(
username=form.cleaned_data['username'],
password=form.cleaned_data['password1'],
)
# ログイン
login(self.request, user)
return super().form_valid(form)
else:
# 通常このルートは通らない
return redirect(reverse_lazy('base:top'))
では確認してみましょう。ユーザーを登録すると無事にプロフィール画面に遷移すればOKです。(現時点ではログインページがないのでログインしない状態でアクセスするとエラーとなります。)
最後に
今回は認証されたユーザーのみがアクセス出来るページについて見てきました。次回はログイン処理を実装してきます。
Sponsored Link