目的
- とにかくやりきることが一番の目的
- 毎日発信することで、発信する習慣作り
- 個人開発をやりきることで、実績作り
開発するもの
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_FIELD
にemail
を指定- これにより
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()),
]
会員登録、ログインのフロント修正
修正といっても、username
をemail
に変更するだけ。
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
を最初に推奨された)
今回は二転三転して、時間がかなりかかった。