LoginSignup
0
0

個人開発記録 2024/05/07

Last updated at Posted at 2024-05-07

目的

  • とにかくやりきることが一番の目的
  • 毎日発信することで、発信する習慣作り
  • 個人開発をやりきることで、実績作り

開発するもの

X(旧Twitter)のパクリ

構成

  • バックエンド
    • python
    • django REST framework
  • DB
    • postgreSQL
  • フロントエンド
    • React

前回

本編

今回は必須項目をusernameからemailに変更しようかと思います。

dj-rest-authをインストール

Django REST Frameworkを使ったユーザー認証をするための便利パッケージ。
※django-rest-authと間違わないように

Userモデルの修正

大きな変更点は以下。

  • Userの修正
    • Userの継承をAbstractUserからAbstractBaseUserに変更
    • USERNAME_FIELDemailを指定
      • これによりusernameの代わりにemailを使用できるようになる
  • UserManagerの追加
    • これによりemailを必須項目にできる
likeX/user/models.py
class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **extra_fields):
        if not email:
            raise ValueError("The Email field must be set")
        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_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault("is_staff", True)
        extra_fields.setdefault("is_superuser", True)

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


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(unique=True)
    first_name = models.CharField(max_length=30, blank=True)
    last_name = models.CharField(max_length=30, blank=True)
    bio = models.CharField(max_length=280, blank=True)
    location = models.CharField(max_length=100, blank=True)
    birth_date = models.DateField(null=True, blank=True)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    # superuserを作成する際にemail以外で追加で必須にする項目を定義
    REQUIRED_FIELDS = []

    def __str__(self):
        return self.email

マイグレーションを実行。

python manage.py makemigrations
python manage.py migrate

CustomLoginSerializerを作成

今回から追加したdj-rest-authのLoginSerializerを継承。

likeX/user/serializers.py
from dj_rest_auth.serializers import LoginSerializer
from django.contrib.auth import authenticate
from rest_framework import serializers

class CustomLoginSerializer(LoginSerializer):
    username = None
    email = serializers.EmailField(required=True)

    def get_auth_user(self, username, email, password):
        user = authenticate(username=email, password=password)
        if not user:
            raise serializers.ValidationError("Invalid email or password")
        return user

CustomLoginViewを作成

こちらもdj-rest-authのLoginViewを継承。
urls.pyでCustomLoginViewを使用するように修正。

likeX/user/views.py
class CustomLoginView(LoginView):
    serializer_class = CustomLoginSerializer
likeX/user/urls.py
urlpatterns = [
    re_path(r'^register/$', UserRegister.as_view()),
    path('login/', CustomLoginView.as_view()),
]

会員登録、ログインのフロント修正

修正といっても、usernameemailに変更するだけ。

src/auth/components/RegisterForm.jsx
  const handleSubmit = (event) => {
    event.preventDefault();
    const data = new FormData(event.currentTarget);

    // FormDataから直接データを取得してオブジェクトに格納し、usernameをfirstNameとlastNameから構成
    const registrationData = {
      email: data.get('email'),
      password: data.get('password'),
      // 削除→ username: `${data.get('firstName')}${data.get('lastName')}`
      first_name: data.get('firstName'),
      last_name: data.get('lastName')
    };

    // API 関数を使用してデータを送信
    registerUser(registrationData)
      .then((response) => {
        console.log('Registration successful:', response);
        // ここに成功時の処理を書く、例えばログインページへリダイレクト等
      })
      .catch((error) => {
        console.error('Registration failed:', error);
        // ここにエラー処理を書く、例えばエラーメッセージの表示等
      });
  };
src/auth/components/LoginForm.jsx
  const handleSubmit = (event) => {
    event.preventDefault();
    const data = new FormData(event.currentTarget);

    const loginData = {
      // 削除→ username: data.get('email'),
      email: data.get('email'),
      password: data.get('password'),
    };

    // API 関数を使用してデータを送信
    login(loginData)
      .then((response) => {
        console.log('Registration successful:', response);
        // ここに成功時の処理を書く、例えばログインページへリダイレクト等
      })
      .catch((error) => {
        console.error('Registration failed:', error);
        // ここにエラー処理を書く、例えばエラーメッセージの表示等
      });
  };

CSRFエラーが発生

CSRFエラーが発生していろいろ修正。。
明日整理する。

感想

chat-GPTに効きながら作成していったが、言ってることが正しいのかどうかが判断できないと遅くなる。。
(今回だとdjango-rest-authを最初に推奨された)
今回は二転三転して、時間がかなりかかった。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0