ゆーじぇいブログ

ゆーじぇいブログ

プログラミングとか色々

[Django]サインアップ機能

f:id:jyouj:20181124164719j:plain

 より良いプログラミングの勉強とは何だろうと考えてみたら、知識をアウトプットすることだ!と思ったので、ブログを開設してみました。学習記録として活用していきたいです。

 主に使っている言語はPythonなので、Djangoの記事が多めになりますね。

 Webサービスを作るため、まずは認証機能に取り掛かりました。メアドで登録できるようにします。

 使うのはpython3.6、Django2.0です。
 参考:Userモデルのカスタマイズ - naritoブログ
    GitHub - benigls/instagram: Instagram clone made with Django framework.


サインアップ機能

 startappしてusersというアップを作成
 settings.pyに

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'users', #追加
]

 ユーザーモデルをカスタマイズします。
 models.pyで

from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import python_2_unicode_compatible

# Create your models here.
class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        if not email:
            raise ValueError("メールアドレスが入力されていません")
        email = self.normalize_email(email)

        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError("スーパーユーザーはis_staff=Trueでなければならない")
        if extra_fields.get('is_superuser') is not True:
            raise ValueError("スーパーユーザーはis_superuser=Trueでなければならない")

        return self._create_user(email, password, **extra_fields)

@python_2_unicode_compatible
class User(AbstractBaseUser):
    email = models.EmailField(max_length=255, unique=True,)
    username = models.CharField(max_length=50, unique=True,)
    name = models.CharField(max_length=50, blank=True,)
    about_me = models.TextField(blank=True)

    date_joined = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    is_admin = models.BooleanField(default=True)
    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_("ユーザーがこのサイトにログインできるかどうか決める"),
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            "このユーザーがactiveとして扱われるべきかどうか定義する"
        ),
    )

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['username',]

    def get_name(self):
        return self.name

    def __str__(self):
        return "@{}".format(self.username)

 settings.pyに以下を追記。

AUTH_USER_MODEL = 'users.User'

 users/forms.pyに

from django import forms
from django.contrib.auth import authenticate
from django.core.exceptions import ValidationError
from django.core.validators import validate_email

from users.models import User

class SignUpForm(forms.ModelForm):
    name = forms.CharField(
        max_length=50,
        help_text='50字以内',
        widget=forms.TextInput(attrs={'placeholder': "ユーザー名"}),
    )
    email = forms.EmailField(
        widget=forms.EmailInput(attrs={'placeholder': "メールアドレス"}),
    )
    password = forms.CharField(
        widget=forms.PasswordInput(attrs={'placeholder': "パスワード"}),
    )
    username = forms.CharField(
        widget=forms.TextInput(attrs={'placeholder': "ユーザーID 入力必須"})
    )

    class Meta:
        model = User
        fields = ('name', 'email', 'password', 'username',)

    def save(self, commit=True):
        user = super(SignUpForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password"])
        if commit:
            user.save()
        return user

 次にviews.pyを編集した。

from __future__ import absolute_import

from django.shortcuts import render, redirect
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import CreateView
from django.urls import reverse_lazy

from .models import User
from .forms import SignUpForm

# Create your views here.
class SignUpView(CreateView):
    model = User
    form_class = SignUpForm
    success_url = reverse_lazy('users:login')
    template_name = 'users/signup.html'

 プロジェクトフォルダーのurls.pyに

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('users.urls', namespace='users')),
]

とした上で、users/urls.pyを作成して、編集。

from django.urls import path
from . import views

app_name = 'users'
urlpatterns = [
    path('signup', views.SignUpView.as_view(), name='signup'),

 settings.pyに以下を追記して、プロジェクトファイル直下にtemplates/usersを作成。

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.normpath(os.path.join(BASE_DIR, 'templates')),], #追記
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

 templates/users/signup.htmlを作成。bootstrap(Bootstrap · The most popular HTML, CSS, and JS library in the world.)を利用した。

{% block body %}
<div>
  <form role="form" action="{% url 'users:signup' %}" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <h3>アカウント登録</h3>
    <div>
      <label for="id_username">ユーザー名:</label>
      {{ form.name }}
      <p>{{ form.name.help_text }}</p>
    </div>
    <div>
      <label for="id_email">メールアドレス:</label>
      {{ form.email }}
    </div>
    <div>
      <label for="id_password">パスワード:</label>
      {{ form.password }}
    </div>
    <div>
      <label for="id_username">ユーザーID:</label>
      @{{ form.username }}
    <div>
      <button class="btn btn-primary" type="submit">登録</button>
    </div>
  </form>
</div>
<div>
</div>
{% endblock %}

 はじめてのブログ投稿だったので、意味不明なところや抜けているところがあるかもしれません。次はログイン・ログアウト機能について書こうと思います。
 
 何かありましたら、以下へ。
 Twitterアカウント:じぇい👨‍💻 (@jyouj__) | Twitter