djangoでユーザ登録画面をデザインする

2022年5月3日

djangoでユーザ登録画面をデザインする

前回のこちらの記事でアカウント周りの機能を実装してみました。
今回はエラーの表示とデザインを実装させてみましょう。

参考:
  djangoでシンプルなフォームを実装しています。
  Django allauthにおけるログイン画面の作成

  djangoは情報が少ないのでこちらの方のブログはかなり助かります。
  Django、フォームの表示方法まとめ

  CSSは毎回色々忘れるので...
  ゼロから始めるHTML/CSS講座marginとpadding

  マウスホバー時色を指定しないで白く出来たので...
  【css】マウスオーバーで画像を白っぽく【簡単コピペ】

階層

階層を見てみましょう。
base.html以外はすべて「django-allauth」のテンプレートを上書きしています。


.
├── accounts
│   ├── templates
│   │   └── account
│   │       ├── base.html
│   │       ├── email_confirm.html
│   │       ├── login.html
│   │       ├── password_reset_done.html
│   │       ├── password_reset_from_key.html
│   │       ├── password_reset.html
│   │       └── signup.html

base.html

base.htmlにはヘッダー下にメッセージを表示する「message-container」を用意してそこにメッセージデータをアサインするようにいたしました。


{% load static %}
<!DOCTYPE html>
<html>
<head>
    <title>Marketista</title>
    <script src="{% static 'js/jquery-3.5.1.min.js' %}"></script>
    <script src="{% static 'js/app.js' %}"></script>
    <link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
</head>
<body>
    <div class="header-title">Marketista</div>
    <div class="message-container">
        {% for errors in form.errors.values %}
            {% for error in errors %}
                <div class="error-message">{{ error }}</div><br>
            {% endfor %}
        {% endfor %}
    </div>
    <div class="main-container">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

signup.html


{% extends 'account/base.html' %}
{% block content %}
{% load widget_tweaks %}
<div class="form-container">
    <div class="form-title">Sign Up</div>
    <form method="post" action="{% url 'account_signup' %}">
        {% csrf_token %}
        {% for field in form %}
            <div>{{ field |add_class:"form-box" }}</div>
        {% endfor %}
        {% if redirect_field_value %}
            <input type="hidden" name="{{ redirect_field_name}}" value="{{ redirect_field_value }}" />
        {% endif %}
        <button class="form-button" type="submit">登録</button>
    </form>
</div>

email_confirm


{% extends 'account/base.html' %}
{% block content %}
{% load widget_tweaks %}
<div class="form-container">
{% if confirmation %}
    <p>ボタンを押してユーザー登録を確定して下さい。</p>
    <form method="post" action="{% url 'account_confirm_email' confirmation.key %}">
        {% csrf_token %}
        <button class="form-button" type="submit">確定</button>
    </form>
{% else %}
    {% url 'account_email' as email_url %}
    <p>リンクの有効期限が過ぎています。<a> href="{{ email_url }}"</a>.</p>
</div>
{% endif %}
{% endblock %}

login.html


{% extends 'account/base.html' %}
{% block content %}
{% load widget_tweaks %}
<div class="form-container">
    <div class="form-title">Login</div>
    <form method="post" action="{% url 'account_login' %}">
        {% csrf_token %}
        <div>{{ form.login |add_class:"form-box" }}</div>
        <div>{{ form.password |add_class:"form-box" }}</div>
        <div class="form-text">ログインしたままにする{{ form.remember }}</div>
        {% if redirect_field_value %}
        <input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
        {% endif %}
        <button class="form-button" type="submit">ログイン</button>
        <p><a href="{% url 'account_reset_password' %}">パスワードを忘れましたか?</a></p>
    </form>
</div>
{% endblock %}

password_reset.html


{% extends 'account/base.html' %}
{% block content %}
{% load widget_tweaks %}
<div class="form-container">
    <div class="form-title">Password Reset</div>
    {% if user.is_authenticated %}
        {% include "accout/snippets/already_logged_in.html" %}
    {% endif %}
    <div class="form-text">パスワードリセット用メールを送信します。</div>
    <form method="post" action="{% url 'account_reset_password' %}">
        {% csrf_token %}
        {{ form.email |add_class:"form-box" }}
        <button class="form-button" type="submit">送信</button>
    </form>
</div>
{% endblock %}

password_reset_done


{% extends 'account/base.html' %}
{% block content %}
{% load widget_tweaks %}
<h1>パスワードリセット</h1>
{% if user.is_authenticated %}
    {% include "account/snippets/already_logged_in.html" %}
{% endif %}
<p>パスワードリセット用のメールを送信しました。</p>
{% endblock %}

password_reset_from_key


{% extends 'account/base.html' %}
{% block content %}
{% load widget_tweaks %}
<div class="form-container">
    <div class="form-title">{% if token_fail %}Invalid Token{% else %}Password Reregist{% endif %}</div>
    {% if token_fail %}
        {% url 'account_reset_password' as passwd_reset_url %}
        <div class="form-text">パスワードリセット用リンクは無効になっています。</div>
        <a href="{{ passwd_reset_url }}">パスワードリセット再申請</a>
    {% else %}
        {% if form %}
            <form method="post" action="{{ action_url }}"> 
                {% csrf_token %}
                <div>{{ form.password1 |add_class:"form-box" }}</div>
                <div>{{ form.password2 |add_class:"form-box" }}</div>
                <button class="form-button" type="submit">変更</button>
            </form>
        {% else %}
            <p>パスワードは変更されています。</p>
        {% endif %}
    {% endif %}
</div>
{% endblock %}

CSS


/*--メイン---------------------------------------------------*/
body {
  margin: 0;
  padding: 0;
}
.header-title{
  color: white;
  font-size: 20px;
  margin-top: 0;
  padding: 10px;
  font-size: 35px;
  background: #1DA1F2;
  color: #fff;
  text-align: center;
  box-shadow: 0 1px 8px #777;
  text-shadow: 1px 1px 1px #777;
}
.main-container{
  width: 70%;
  margin: auto;
}
/*--メッセージ-----------------------------------------------*/
.message-container{
  padding: 10px;
  height: 50px;
  display: flex; /*子要素を縦横中央寄せ*/
  align-items: center; /*子要素を縦横中央寄せ*/
  justify-content: center; /*子要素を縦横中央寄せ*/
}
.errorlist{
  color: red;
}
.error-message{
  color: red;
}
/*--フォーム-------------------------------------------------*/
/*フォームコンテナ*/
.form-container{
  background: white;
  padding: 20px; /*内側余白*/
  margin: auto; /*中央揃え*/
  margin-top: 10px; /*上部余白*/
  width: 400px; /*横幅*/
  border-radius: 4px; /*外角の丸み*/
  border: 1px solid #ddd; /*枠線*/
  text-align: center; /*内部の要素を中央ぞろえ*/
}
/*フォーム内*/
.form-title{
  color: #808080; /*文字色*/
  margin: 10px; /*外余白*/
}
.form-box{
  border: none; /*枠線を消す*/
  border-radius: 4px; /*外角の丸み*/
  border: 1px solid #ddd; /*枠線*/
  margin: 10px; /*外余白*/
  height: 29px; /*縦幅*/ 
  width: 80%; /*横幅*/
}
.form-button{
  text-align: center; /*中央揃え*/
  border: none; /*枠線を消す*/ 
  border-radius: 4px; /*外角の丸み*/
  width: 80%; /*横幅*/
  height: 29px; /*縦幅*/ 
  margin: 10px; /*外余白*/
  background-color:  #1DA1F2; /*背景色*/
  color: white; /*文字色*/
}
.form-button:hover{
  opacity: 0.6; filter: brightness(110%); /*ホバー時に白くする*/
}
.form-text{
  color: #808080; /*文字色*/
}

最後に

タイトルの「Marketista」はMarketingをもじって付けました。
このご時世SNSのDMを使用してマーケティングをしている企業が多いみたいです。私の友人の会社ももっぱらマーケティングはSNSみたいです。
なので出来ればSNSマーケティングをブラウザから効率よく行えるツールを作ってみたいと思いこんな名前にしてみました。

twitterAPIを使って特定のユーザーにDMを自動化したり、ツイートを「わかちがき」して分析したりなどやってみたいです。

なんにせよアカウント周りが完成したのでこれからアプリの実装です!

YouTube

2022年5月3日