diff --git a/.idea/.idea/.gitignore b/.idea/.idea/.gitignore
new file mode 100644
index 0000000..e69de29
diff --git a/.idea/.idea/.idea.iml b/.idea/.idea/.idea.iml
new file mode 100644
index 0000000..d0876a7
--- /dev/null
+++ b/.idea/.idea/.idea.iml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea/inspectionProfiles/Project_Default.xml b/.idea/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..5204d19
--- /dev/null
+++ b/.idea/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea/inspectionProfiles/profiles_settings.xml b/.idea/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea/misc.xml b/.idea/.idea/misc.xml
new file mode 100644
index 0000000..50dc922
--- /dev/null
+++ b/.idea/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea/modules.xml b/.idea/.idea/modules.xml
new file mode 100644
index 0000000..08f54a6
--- /dev/null
+++ b/.idea/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea/workspace.xml b/.idea/.idea/workspace.xml
new file mode 100644
index 0000000..0b98e2e
--- /dev/null
+++ b/.idea/.idea/workspace.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1691050027413
+
+
+ 1691050027413
+
+
+
+
+
+
+
+
+
+
+
+ file://$PROJECT_DIR$/main.py
+ 8
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.vs/.idea/v16/.suo b/.idea/.vs/.idea/v16/.suo
new file mode 100644
index 0000000..8208ead
Binary files /dev/null and b/.idea/.vs/.idea/v16/.suo differ
diff --git a/.idea/.vs/ProjectSettings.json b/.idea/.vs/ProjectSettings.json
new file mode 100644
index 0000000..f8b4888
--- /dev/null
+++ b/.idea/.vs/ProjectSettings.json
@@ -0,0 +1,3 @@
+{
+ "CurrentProjectSetting": null
+}
\ No newline at end of file
diff --git a/.idea/.vs/VSWorkspaceState.json b/.idea/.vs/VSWorkspaceState.json
new file mode 100644
index 0000000..6b61141
--- /dev/null
+++ b/.idea/.vs/VSWorkspaceState.json
@@ -0,0 +1,6 @@
+{
+ "ExpandedNodes": [
+ ""
+ ],
+ "PreviewInSolutionExplorer": false
+}
\ No newline at end of file
diff --git a/.idea/.vs/slnx.sqlite b/.idea/.vs/slnx.sqlite
new file mode 100644
index 0000000..fde3847
Binary files /dev/null and b/.idea/.vs/slnx.sqlite differ
diff --git a/.idea/main.py b/.idea/main.py
new file mode 100644
index 0000000..5596b44
--- /dev/null
+++ b/.idea/main.py
@@ -0,0 +1,16 @@
+# This is a sample Python script.
+
+# Press Shift+F10 to execute it or replace it with your code.
+# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
+
+
+def print_hi(name):
+ # Use a breakpoint in the code line below to debug your script.
+ print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint.
+
+
+# Press the green button in the gutter to run the script.
+if __name__ == '__main__':
+ print_hi('PyCharm')
+
+# See PyCharm help at https://www.jetbrains.com/help/pycharm/
diff --git a/Exer/__pycache__/models.cpython-310.pyc b/Exer/__pycache__/models.cpython-310.pyc
index d18e80e..cae4467 100644
Binary files a/Exer/__pycache__/models.cpython-310.pyc and b/Exer/__pycache__/models.cpython-310.pyc differ
diff --git a/Exer/__pycache__/serializers.cpython-310.pyc b/Exer/__pycache__/serializers.cpython-310.pyc
index d2aa1c0..3decf9e 100644
Binary files a/Exer/__pycache__/serializers.cpython-310.pyc and b/Exer/__pycache__/serializers.cpython-310.pyc differ
diff --git a/Exer/__pycache__/views.cpython-310.pyc b/Exer/__pycache__/views.cpython-310.pyc
index 03e9d09..2a47620 100644
Binary files a/Exer/__pycache__/views.cpython-310.pyc and b/Exer/__pycache__/views.cpython-310.pyc differ
diff --git a/Exer/models.py b/Exer/models.py
index 4eed0c2..1d35b4e 100644
--- a/Exer/models.py
+++ b/Exer/models.py
@@ -3,11 +3,13 @@
class Exercise(models.Model):
exercise_id = models.IntegerField(primary_key=True)
usebody = models.ForeignKey('usebody.Usebody', on_delete=models.CASCADE, max_length=11)
+
exerciseName_English= models.CharField(max_length=50, blank=True, null=True)
exerciseName_Korean = models.CharField(max_length=50, blank=True, null=True)
equipment_name = models.CharField(max_length=50, blank=True, null=True)
videolink = models.CharField(max_length=150, blank=True, null=True)
+
class Meta:
managed = False
db_table = 'exercise'
diff --git a/Exer/serializers.py b/Exer/serializers.py
index f73aba0..96afb9f 100644
--- a/Exer/serializers.py
+++ b/Exer/serializers.py
@@ -1,12 +1,22 @@
from rest_framework import serializers
from .models import Exercise
+from usebody.models import Usebody
+class BodySerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Usebody
+ fields= '__all__'
class ExerciseDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Exercise
- fields = ['exerciseName_English', 'exerciseName_Korean', 'equipment_name', 'videolink']
+ fields = ['usebody_id','exerciseName_English', 'exerciseName_Korean', 'equipment_name', 'videolink']
class ExerciseSerializer(serializers.ModelSerializer):
+ #usebody_name = serializers.SerializerMethodField()
+
+ # def get_usebody_name(self, obj):
+ # return obj.usebody_name
class Meta:
model = Exercise
+
fields = ['usebody_id', 'exerciseName_English', 'exerciseName_Korean']
diff --git a/Exer/views.py b/Exer/views.py
index 29e3a32..1c3b4d4 100644
--- a/Exer/views.py
+++ b/Exer/views.py
@@ -7,16 +7,28 @@
from Exer.serializers import ExerciseDetailSerializer
from django.shortcuts import get_object_or_404
+from django.db import connection
#03-01 부위별 운동 간단 조회
-#usebody의 id 대신 name이 나오게 하려면 model을 수정해야 할 것으로 보임
class ExerciseBodyAPIiew(APIView):
def get_object(self,pk):
return Exercise.objects.filter(usebody_id=pk)
def get(self,request,pk):
+ #pk를 usebody_id를 가지는 객체를 가져온다
+ cursor = connection.cursor()
+ sql = "select usebody_name from usebody where usebody_id = %s"
+ cursor.execute(sql, [pk])
+ result = cursor.fetchall()
+
exercise = self.get_object(pk)
serializer = ExerciseSerializer(exercise, many=True)
+
+ for i in serializer.data:
+ key = f'usebody_name'
+ value= result[0][0]
+ i[key] = value
+
return Response(serializer.data)
@@ -33,12 +45,36 @@ def get(self, request,pk):
#03-03 운동 검색
class ExerciseSearchAPIView(APIView):
def post(self,request):
- data = request.data
+ if request.body:
+ objectsKor = Exercise.objects.filter(exerciseName_English__icontains=request.data.get('searchData'))
+ objectsEng = Exercise.objects.filter(exerciseName_Korean__icontains=request.data.get('searchData'))
+
+ combined_objects = list(objectsKor) + list(objectsEng)
+
+ body = []
- exercise = Exercise.objects.filter(exerciseName_Korean=data)
- serializer = ExerciseSerializer(exercise)
+ for i in combined_objects:
+ u_id = i.usebody_id
+
+ cursor = connection.cursor()
+ sql = "select usebody_name from usebody where usebody_id = %s"
+ cursor.execute(sql, [u_id])
+ result = cursor.fetchall()
+ body.append(result[0][0])
+
+ serializer = ExerciseSerializer(combined_objects, many=True)
+
+ index = 0
+ for i in serializer.data:
+
+ key = f'usebody_name'
+ value = body[index]
+ i[key] = value
+ index+=1
- if serializer.is_valid():
return Response(serializer.data)
- return Response(serializer.errors)
+ else:
+ objects = Exercise.objects.all()
+ serializer = ExerciseSerializer(objects, many=True)
+ return Response(serializer.data)
diff --git a/__pycache__/my_settings.cpython-310.pyc b/__pycache__/my_settings.cpython-310.pyc
index a54f124..6d6daec 100644
Binary files a/__pycache__/my_settings.cpython-310.pyc and b/__pycache__/my_settings.cpython-310.pyc differ
diff --git a/accounts/__pycache__/__init__.cpython-311.pyc b/accounts/__pycache__/__init__.cpython-311.pyc
index 0fa8d19..3116271 100644
Binary files a/accounts/__pycache__/__init__.cpython-311.pyc and b/accounts/__pycache__/__init__.cpython-311.pyc differ
diff --git a/accounts/__pycache__/admin.cpython-311.pyc b/accounts/__pycache__/admin.cpython-311.pyc
index 6ae62fb..13a6519 100644
Binary files a/accounts/__pycache__/admin.cpython-311.pyc and b/accounts/__pycache__/admin.cpython-311.pyc differ
diff --git a/accounts/__pycache__/apps.cpython-311.pyc b/accounts/__pycache__/apps.cpython-311.pyc
index c4fcda8..e52b135 100644
Binary files a/accounts/__pycache__/apps.cpython-311.pyc and b/accounts/__pycache__/apps.cpython-311.pyc differ
diff --git a/accounts/__pycache__/backends.cpython-310.pyc b/accounts/__pycache__/backends.cpython-310.pyc
new file mode 100644
index 0000000..19aee23
Binary files /dev/null and b/accounts/__pycache__/backends.cpython-310.pyc differ
diff --git a/accounts/__pycache__/backends.cpython-311.pyc b/accounts/__pycache__/backends.cpython-311.pyc
new file mode 100644
index 0000000..99fc45a
Binary files /dev/null and b/accounts/__pycache__/backends.cpython-311.pyc differ
diff --git a/accounts/__pycache__/models.cpython-310.pyc b/accounts/__pycache__/models.cpython-310.pyc
index 032892a..7be31ab 100644
Binary files a/accounts/__pycache__/models.cpython-310.pyc and b/accounts/__pycache__/models.cpython-310.pyc differ
diff --git a/accounts/__pycache__/models.cpython-311.pyc b/accounts/__pycache__/models.cpython-311.pyc
index 7be3c70..4f708ac 100644
Binary files a/accounts/__pycache__/models.cpython-311.pyc and b/accounts/__pycache__/models.cpython-311.pyc differ
diff --git a/accounts/__pycache__/serializers.cpython-310.pyc b/accounts/__pycache__/serializers.cpython-310.pyc
new file mode 100644
index 0000000..c148aa9
Binary files /dev/null and b/accounts/__pycache__/serializers.cpython-310.pyc differ
diff --git a/accounts/__pycache__/serializers.cpython-311.pyc b/accounts/__pycache__/serializers.cpython-311.pyc
new file mode 100644
index 0000000..2336dae
Binary files /dev/null and b/accounts/__pycache__/serializers.cpython-311.pyc differ
diff --git a/accounts/__pycache__/urls.cpython-310.pyc b/accounts/__pycache__/urls.cpython-310.pyc
new file mode 100644
index 0000000..756a16e
Binary files /dev/null and b/accounts/__pycache__/urls.cpython-310.pyc differ
diff --git a/accounts/__pycache__/urls.cpython-311.pyc b/accounts/__pycache__/urls.cpython-311.pyc
new file mode 100644
index 0000000..ca48bc4
Binary files /dev/null and b/accounts/__pycache__/urls.cpython-311.pyc differ
diff --git a/accounts/__pycache__/utils.cpython-310.pyc b/accounts/__pycache__/utils.cpython-310.pyc
new file mode 100644
index 0000000..9a133bd
Binary files /dev/null and b/accounts/__pycache__/utils.cpython-310.pyc differ
diff --git a/accounts/__pycache__/utils.cpython-311.pyc b/accounts/__pycache__/utils.cpython-311.pyc
new file mode 100644
index 0000000..b536f2c
Binary files /dev/null and b/accounts/__pycache__/utils.cpython-311.pyc differ
diff --git a/accounts/__pycache__/views.cpython-310.pyc b/accounts/__pycache__/views.cpython-310.pyc
new file mode 100644
index 0000000..4bb9c9b
Binary files /dev/null and b/accounts/__pycache__/views.cpython-310.pyc differ
diff --git a/accounts/__pycache__/views.cpython-311.pyc b/accounts/__pycache__/views.cpython-311.pyc
new file mode 100644
index 0000000..e79ff24
Binary files /dev/null and b/accounts/__pycache__/views.cpython-311.pyc differ
diff --git a/accounts/backends.py b/accounts/backends.py
new file mode 100644
index 0000000..97d7780
--- /dev/null
+++ b/accounts/backends.py
@@ -0,0 +1,18 @@
+import bcrypt
+from django.contrib.auth import get_user_model
+from django.contrib.auth.backends import ModelBackend
+from django.contrib.auth.hashers import check_password
+from django.db.models import Q
+
+
+class EmailBackend(ModelBackend):
+ def authenticate(self, request, username=None, password=None, **kwargs):
+ UserModel = get_user_model()
+ try:
+ user = UserModel.objects.get(email=username)
+ except UserModel.DoesNotExist:
+ return None
+ else:
+ if user.check_password(password):
+ return user
+ return None
\ No newline at end of file
diff --git a/accounts/migrations/0001_initial.py b/accounts/migrations/0001_initial.py
new file mode 100644
index 0000000..3d97d95
--- /dev/null
+++ b/accounts/migrations/0001_initial.py
@@ -0,0 +1,35 @@
+# Generated by Django 4.2.3 on 2023-08-15 16:59
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ ('auth', '0012_alter_user_first_name_max_length'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='User',
+ fields=[
+ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('password', models.CharField(max_length=128, verbose_name='password')),
+ ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
+ ('email', models.EmailField(blank=True, max_length=100, unique=True)),
+ ('nickname', models.CharField(blank=True, max_length=20, unique=True)),
+ ('is_superuser', models.BooleanField(default=False)),
+ ('is_active', models.BooleanField(default=True)),
+ ('is_staff', models.BooleanField(default=False)),
+ ('created_at', models.DateTimeField(auto_now_add=True)),
+ ('updated_at', models.DateTimeField(auto_now=True)),
+ ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
+ ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
+ ],
+ options={
+ 'abstract': False,
+ },
+ ),
+ ]
diff --git a/accounts/migrations/__pycache__/0001_initial.cpython-310.pyc b/accounts/migrations/__pycache__/0001_initial.cpython-310.pyc
new file mode 100644
index 0000000..74b4ffe
Binary files /dev/null and b/accounts/migrations/__pycache__/0001_initial.cpython-310.pyc differ
diff --git a/accounts/migrations/__pycache__/0001_initial.cpython-311.pyc b/accounts/migrations/__pycache__/0001_initial.cpython-311.pyc
new file mode 100644
index 0000000..6f5d180
Binary files /dev/null and b/accounts/migrations/__pycache__/0001_initial.cpython-311.pyc differ
diff --git a/accounts/migrations/__pycache__/__init__.cpython-311.pyc b/accounts/migrations/__pycache__/__init__.cpython-311.pyc
index 33b3d36..221fc72 100644
Binary files a/accounts/migrations/__pycache__/__init__.cpython-311.pyc and b/accounts/migrations/__pycache__/__init__.cpython-311.pyc differ
diff --git a/accounts/models.py b/accounts/models.py
index 988363b..bffbea0 100644
--- a/accounts/models.py
+++ b/accounts/models.py
@@ -1,24 +1,82 @@
+from django.contrib.auth.base_user import BaseUserManager
from django.db import models
+from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
-# Create your models here.
-class User(models.Model):
- user_id = models.IntegerField(primary_key=True)
- nickname = models.CharField(max_length=10, blank=True, null=True)
- password = models.CharField(max_length=20, blank=True, null=True)
- email = models.CharField(max_length=100, blank=True, null=True)
- class Meta:
- managed = False
- db_table = 'user'
+# class User(models.Model):
+# user_id = models.IntegerField(primary_key=True)
+# nickname = models.CharField(max_length=10, blank=True, null=True)
+# password = models.CharField(max_length=20, blank=True, null=True)
+# email = models.CharField(max_length=100, blank=True, null=True)
+#
+# # USERNAME_FIELD = 'email'
+# # REQUIRED_FIELDS = ['username']
+#
+# class Meta:
+# managed = False
+# db_table = 'user'
+# db_table_comment = '사용자 데이터'
+
+
+class UserManager(BaseUserManager):
+ def create_user(self, email, nickname, password, **kwargs):
+ if not email:
+ raise ValueError('Users must have an email address')
+
+ user = self.model(
+ email=self.normalize_email(email),
+ nickname=nickname
+ )
+ user.set_password(password)
+ user.save(using=self._db)
+ return user
+
+ def create_superuser(self, email=None, nickname=None, password=None):
+ superuser = self.create_user(
+ email=email,
+ nickname=nickname,
+ password=password,
+ )
+ superuser.is_staff = True
+ superuser.is_superuser = True
+ superuser.is_active = True
+ superuser.save(using=self._db)
+ return superuser
+
+class User(AbstractBaseUser, PermissionsMixin):
+ objects = UserManager()
+
+ email = models.EmailField(max_length=100, blank=False, null=False, unique=True)
+ nickname = models.CharField(max_length=20, blank=False, null=False, unique=True)
+
+ is_superuser = models.BooleanField(default=False)
+ is_active = models.BooleanField(default=True)
+ is_staff = models.BooleanField(default=False)
+ created_at = models.DateTimeField(auto_now_add=True)
+ updated_at = models.DateTimeField(auto_now=True)
+
+ USERNAME_FIELD = 'email'
+ REQUIRED_FIELDS = ['nickname']
class Userinfo(models.Model):
- user = models.ForeignKey(User, models.DO_NOTHING, blank=True, null=True)
+ user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user")
height = models.IntegerField(blank=True, null=True)
weight = models.FloatField(blank=True, null=True)
bmi = models.FloatField(blank=True, null=True)
- info = models.CharField(max_length=100, blank=True, null=True)
- accvisibility = models.IntegerField(db_column='accVisibility', blank=True, null=True) # Field name made lowercase.
+ info = models.CharField(max_length=150, blank=True, null=True)
+ acc_visibility = models.IntegerField()
class Meta:
managed = False
db_table = 'userinfo'
+
+
+class Follow(models.Model):
+ id = models.AutoField(primary_key=True)
+ follower = models.ForeignKey(User, related_name='follower', on_delete=models.CASCADE)
+ following = models.ForeignKey(User, related_name='following', on_delete=models.CASCADE)
+ created_at = models.DateTimeField(auto_now_add=True)
+
+ class Meta:
+ managed = False
+ db_table = 'follow'
diff --git a/accounts/serializers.py b/accounts/serializers.py
index e69de29..e1c012b 100644
--- a/accounts/serializers.py
+++ b/accounts/serializers.py
@@ -0,0 +1,29 @@
+import requests
+from rest_framework import serializers
+
+from accounts.models import User, Follow, Userinfo
+
+
+class UserSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = User
+ fields = '__all__'
+
+ def create(self, validated_data):
+ user = User.objects.create_user(
+ email=validated_data['email'],
+ nickname=validated_data['nickname'],
+ password=validated_data['password']
+ )
+ return user
+
+
+class FollowSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Follow
+ fields = '__all__'
+
+class UserinfoSerializer(serializers.ModelSerializer):
+ class Meta:
+ model = Userinfo
+ fields = '__all__'
diff --git a/accounts/urls.py b/accounts/urls.py
new file mode 100644
index 0000000..a34cb24
--- /dev/null
+++ b/accounts/urls.py
@@ -0,0 +1,13 @@
+from django.urls import path, include
+
+from accounts.views import SigninAPIView, AuthAPIView, FollowAPIView, UserinfoAPIView, UserDetailAPIView
+
+urlpatterns = [
+ # path('', include('dj_rest_auth.urls')),
+ # path('signin/', include('dj_rest_auth.registration.urls')),
+ path('signin/', SigninAPIView.as_view()),
+ path('auth/', AuthAPIView.as_view()),
+ path('follow/', FollowAPIView.as_view()),
+ path('info/', UserinfoAPIView.as_view()),
+ path('/', UserDetailAPIView.as_view()),
+]
\ No newline at end of file
diff --git a/accounts/utils.py b/accounts/utils.py
new file mode 100644
index 0000000..a216da4
--- /dev/null
+++ b/accounts/utils.py
@@ -0,0 +1,25 @@
+import jwt
+import json
+
+from django.http import JsonResponse
+from rest_framework import status
+from rest_framework.response import Response
+
+from accounts.models import User
+from my_settings import SECRET_KEY
+
+
+def login_check(func):
+ def wrapper(self, request, *args, **kwargs):
+ try:
+ access = request.COOKIES.get('access')
+ # access_token = request.headers.get('Authorization', None)
+ payload = jwt.decode(access, SECRET_KEY, algorithms='HS256')
+ user = User.objects.get(id=payload['user_id'])
+ request.user = user
+ except jwt.exceptions.DecodeError:
+ return Response({'message': 'INVALID TOKEN'}, status=status.HTTP_400_BAD_REQUEST)
+ except User.DoesNotExist:
+ return Response({'message': 'INVALID USER'}, status=status.HTTP_400_BAD_REQUEST)
+ return func(self, request, *args, **kwargs)
+ return wrapper
diff --git a/accounts/views.py b/accounts/views.py
index 91ea44a..939efe1 100644
--- a/accounts/views.py
+++ b/accounts/views.py
@@ -1,3 +1,231 @@
-from django.shortcuts import render
+import jwt
+from django.contrib.auth import authenticate
+from django.shortcuts import get_object_or_404
+from rest_framework import status
+from rest_framework.response import Response
+from rest_framework.views import APIView
+from rest_framework_simplejwt.serializers import TokenObtainPairSerializer, TokenRefreshSerializer
-# Create your views here.
+from accounts.models import User, Follow, Userinfo
+from accounts.serializers import UserSerializer, FollowSerializer, UserinfoSerializer
+from accounts.utils import login_check
+from my_settings import SECRET_KEY
+
+
+# 01-01 이메일 회원가입
+class SigninAPIView(APIView):
+ def post(self, request):
+ serializer = UserSerializer(data=request.data)
+ if serializer.is_valid():
+ user = serializer.save()
+
+ # JWT 토큰
+ token = TokenObtainPairSerializer.get_token(user)
+ refresh_token = str(token)
+ access_token = str(token.access_token)
+ res = Response(
+ {
+ "user": serializer.data,
+ "message": "Signin Success",
+ "token": {
+ "access": access_token,
+ "refresh": refresh_token,
+ },
+ },
+ status=status.HTTP_200_OK
+ )
+
+ res.set_cookie("access", access_token, httponly=True)
+ res.set_cookie("refresh", refresh_token, httponly=True)
+
+ return res
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
+
+
+class AuthAPIView(APIView):
+ # 01 token에 따른 user 정보 가져오기
+ def get(self, request):
+ try:
+ access = request.COOKIES.get('access')
+ payload = jwt.decode(access, SECRET_KEY, algorithms=['HS256'])
+ pk = payload.get('user_id')
+ user = get_object_or_404(User, pk=pk)
+ serializer = UserSerializer(instance=user)
+ return Response(serializer.data, status=status.HTTP_200_OK)
+ # token이 만료되었을 때
+ # except(jwt.exceptions.ExpiredSignatureError):
+ # data = {'refresh': request.COOKIES.get('refresh', None)}
+ # serializer = TokenRefreshSerializer(data=data)
+ # if serializer.is_valid(raise_exception=True):
+ # access = serializer.data.get('access', None)
+ # refresh = serializer.data.get('refresh', None)
+ # payload = jwt.decode(access, SECRET_KEY, algorithms=['HS256'])
+ # pk = payload.get('user_id')
+ # user = get_object_or_404(User, pk=pk)
+ # serializer = UserSerializer(instance=user)
+ # res = Response(serializer.data, status=status.HTTP_200_OK)
+ # res.set_cookie('access', access)
+ # res.set_cookie('refresh', refresh)
+ # return res
+ # raise jwt.exceptions.InvalidTokenError
+ except(jwt.exceptions.ExpiredSignatureError):
+ data = {'refresh': request.COOKIES.get('refresh', None)}
+ serializer = TokenObtainPairSerializer(data=data)
+ if serializer.is_valid(raise_exception=True):
+ access = serializer.data.get('access_token', None)
+ refresh = serializer.data.get('refresh_token', None)
+ payload = jwt.decode(access, SECRET_KEY, algorithms=['HS256'])
+ pk = payload.get('user_id')
+ user = get_object_or_404(User, pk=pk)
+ serializer = UserSerializer(instance=user)
+ res = Response(serializer.data, status=status.HTTP_200_OK)
+ res.set_cookie('access_token', access)
+ res.set_cookie('refresh_token', refresh)
+ return res
+ raise jwt.exceptions.InvalidTokenError
+ # 사용 불가능한 토큰일 때
+ except(jwt.exceptions.InvalidTokenError):
+ return Response(status=status.HTTP_400_BAD_REQUEST)
+
+ # 01-02 이메일 로그인
+ def post(self, request):
+ # user 인증
+ user = authenticate(
+ username=request.data.get("email"), password=request.data.get("password")
+ )
+
+ # 회원가입한 user일 경우
+ if user is not None:
+ serializer = UserSerializer(user)
+ # JWT 토큰
+ token = TokenObtainPairSerializer.get_token(user)
+ refresh_token = str(token)
+ access_token = str(token.access_token)
+ res = Response(
+ {
+ "user": serializer.data,
+ "message": "Login Success",
+ "token": {
+ "access": access_token,
+ "refresh": refresh_token
+ },
+ },
+ status=status.HTTP_200_OK
+ )
+ # JWT 토큰을 Cookie에 저장
+ res.set_cookie("access", access_token, httponly=True)
+ res.set_cookie("refresh", refresh_token, httponly=True)
+ return res
+ else:
+ return Response(status=status.HTTP_400_BAD_REQUEST)
+
+ # 01-03 이메일 로그아웃
+ def delete(self, request):
+ response = Response({
+ "message": "Logout Success"
+ }, status=status.HTTP_200_OK)
+ response.delete_cookie("access")
+ response.delete_cookie("refresh")
+ return response
+
+
+class FollowAPIView(APIView):
+ # API 08-01 팔로잉 조회
+ @login_check
+ def get(self, request):
+ user_id = request.user.id
+ following = Follow.objects.filter(follower_id=user_id)
+ serializer = FollowSerializer(following, many=True)
+ return Response(serializer.data)
+
+ # API 08-02, 08-03 팔로우, 언팔로우
+ @login_check
+ def post(self, request):
+ following_id = request.data.get('following_id')
+ user_following = get_object_or_404(User, id=following_id)
+
+ if user_following == request.user:
+ return Response({'message': "Can't Follow Self"}, status=status.HTTP_400_BAD_REQUEST)
+
+ is_following = Follow.objects.filter(follower=request.user, following=user_following).exists()
+
+ if is_following:
+ # 팔로잉 중인 상태: unfollow
+ follow = Follow.objects.get(follower=request.user, following=user_following)
+ follow.delete()
+ message = 'Unfollowed Successfully'
+ else:
+ # 팔로잉 되어 있지 않은 상태: follow
+ Follow.objects.create(follower=request.user, following=user_following)
+ message = 'Followed Successfully'
+
+ return Response({'messages': message}, status=status.HTTP_200_OK)
+
+
+class UserinfoAPIView(APIView):
+ # API 02-01 회원 정보 입력
+ @login_check
+ def post(self, request):
+ # User의 userinfo가 존재하는 지 확인
+ is_exist = Userinfo.objects.filter(user_id=request.user.id)
+ if is_exist:
+ return Response({'message': 'User already had Userinfo'}, status=status.HTTP_400_BAD_REQUEST)
+
+ # user 설정
+ request.data['user'] = request.user.id
+
+ # bmi 계산
+ weight = request.data.get('weight')
+ height = request.data.get('height') * 0.01
+ bmi = round(weight / (height * height), 2)
+ request.data['bmi'] = bmi
+
+ serializer = UserinfoSerializer(data=request.data)
+ if serializer.is_valid():
+ serializer.save()
+ return Response(serializer.data, status=status.HTTP_200_OK)
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
+
+
+ # API 02-03 회원 정보 수정
+ # PUT vs PATCH
+ # PUT : 모든 속성 수정 / PATCH : 일부 속성 수정
+ @login_check
+ def put(self, request):
+ # User의 userinfo가 존재하는 지 확인
+ is_exist = Userinfo.objects.filter(user_id=request.user.id)
+ if not is_exist:
+ return Response({'message': 'No Userinfo'}, status=status.HTTP_400_BAD_REQUEST)
+
+ request.data['user'] = request.user.id
+
+ userinfo = Userinfo.objects.get(user_id=request.user.id)
+
+ # bmi 계산
+ weight = request.data.get('weight')
+ height = request.data.get('height') * 0.01
+ bmi = round(weight / (height * height), 2)
+ request.data['bmi'] = bmi
+
+ serializer = UserinfoSerializer(userinfo, data=request.data)
+ if serializer.is_valid():
+ serializer.save()
+ return Response(serializer.data, status=status.HTTP_200_OK)
+ return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
+
+
+class UserDetailAPIView(APIView):
+ # user_id -> 해당 유저의 상세 정보 조회
+ def get_object(self, pk):
+ return get_object_or_404(User, pk=pk)
+
+ # API 02-02 회원 정보 조회
+ def get(self, request, pk):
+ userinfo = Userinfo.objects.get(user_id=pk)
+
+ # 계정 비공개 일 경우
+ if userinfo.acc_visibility == 0:
+ return Response({'message': 'This account is Private account'}, status=status.HTTP_400_BAD_REQUEST)
+
+ serializer = UserinfoSerializer(userinfo)
+ return Response(serializer.data, status=status.HTTP_200_OK)
\ No newline at end of file
diff --git a/broccoli/__pycache__/settings.cpython-310.pyc b/broccoli/__pycache__/settings.cpython-310.pyc
index 3f113d6..c42abd5 100644
Binary files a/broccoli/__pycache__/settings.cpython-310.pyc and b/broccoli/__pycache__/settings.cpython-310.pyc differ
diff --git a/broccoli/__pycache__/settings.cpython-311.pyc b/broccoli/__pycache__/settings.cpython-311.pyc
index b6b7875..63ff606 100644
Binary files a/broccoli/__pycache__/settings.cpython-311.pyc and b/broccoli/__pycache__/settings.cpython-311.pyc differ
diff --git a/broccoli/__pycache__/urls.cpython-310.pyc b/broccoli/__pycache__/urls.cpython-310.pyc
index 2d57a1a..a2a316e 100644
Binary files a/broccoli/__pycache__/urls.cpython-310.pyc and b/broccoli/__pycache__/urls.cpython-310.pyc differ
diff --git a/broccoli/__pycache__/urls.cpython-311.pyc b/broccoli/__pycache__/urls.cpython-311.pyc
index 6a7a49e..321d621 100644
Binary files a/broccoli/__pycache__/urls.cpython-311.pyc and b/broccoli/__pycache__/urls.cpython-311.pyc differ
diff --git a/broccoli/settings.py b/broccoli/settings.py
index 7376f59..baee38f 100644
--- a/broccoli/settings.py
+++ b/broccoli/settings.py
@@ -9,7 +9,7 @@
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""
-
+from datetime import timedelta
from pathlib import Path
import my_settings
@@ -28,11 +28,26 @@
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
-ALLOWED_HOSTS = []
+#나중에 보안 상의 문제를 수정하려면 *를 삭제해야 함
+ALLOWED_HOSTS = ['*']
# Application definition
+#user 설정
+AUTH_USER_MODEL = 'accounts.User'
+
+AUTHENTICATION_BACKENDS = [
+ 'accounts.backends.EmailBackend',
+ 'django.contrib.auth.backends.ModelBackend',
+]
+
+PASSWORD_HASHERS = [
+ 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher',
+ 'django.contrib.auth.hashers.PBKDF2PasswordHasher',
+ 'django.contrib.auth.hashers.Argon2PasswordHasher',
+]
+
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
@@ -40,9 +55,23 @@
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
+
+ #라이브러리
'rest_framework',
- 'Exer.apps.ExerConfig',
+ 'rest_framework_simplejwt',
+
+
+ # 'allauth',
+ # 'allauth.socialaccount',
+ # 'allauth.account',
+ 'rest_framework.authtoken',
+ # 'rest_auth.registration',
+
+ #연동
+ 'corsheaders',
+ #앱
'usebody.apps.UsebodyConfig',
+ 'Exer.apps.ExerConfig',
'routine.apps.RoutineConfig',
'accounts.apps.AccountsConfig',
]
@@ -54,9 +83,31 @@
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
+ 'corsheaders.middleware.CorsMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
+CORS_ORIGIN_ALLOW_ALL = False
+CORS_ORIGIN_WHITELIST= (
+ 'http://localhost:8080',
+ 'http://192.168.8.139:8080',
+)
+
+REST_FRAMEWORK = {
+ 'DEFAULT_AUTHENTICATION_CLASSES': (
+ 'rest_framework_simplejwt.authentication.JWTAuthentication',
+ ),
+}
+
+#JWT 설정
+SIMPLE_JWT = {
+ 'ACCESS_TOKEN_LIFETIME': timedelta(minutes=30),
+ 'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
+ 'ALGORITHM': 'HS256',
+ 'SIGNING_KEY': SECRET_KEY,
+ 'AUTH_HEADER_TYPES': ('JWT',),
+}
+
ROOT_URLCONF = 'broccoli.urls'
TEMPLATES = [
diff --git a/broccoli/urls.py b/broccoli/urls.py
index b45c9f1..1fd896a 100644
--- a/broccoli/urls.py
+++ b/broccoli/urls.py
@@ -22,4 +22,5 @@
path('exercise/', include('Exer.urls')),
path('usebody/', include('usebody.urls')),
path('routine/', include('routine.urls')),
+ path('accounts/', include('accounts.urls')),
]
diff --git a/my_settings.py b/my_settings.py
index 8519ed8..05817be 100644
--- a/my_settings.py
+++ b/my_settings.py
@@ -6,7 +6,7 @@
'USER': 'root',
'PASSWORD': 'apolonlee9',
'HOST': 'localhost',
- 'PORT': '3308',
+ 'PORT': '3306',
}
}
diff --git a/routine/__pycache__/models.cpython-310.pyc b/routine/__pycache__/models.cpython-310.pyc
index f349bb2..e0e2b08 100644
Binary files a/routine/__pycache__/models.cpython-310.pyc and b/routine/__pycache__/models.cpython-310.pyc differ
diff --git a/routine/__pycache__/serializers.cpython-310.pyc b/routine/__pycache__/serializers.cpython-310.pyc
index da65e99..674591c 100644
Binary files a/routine/__pycache__/serializers.cpython-310.pyc and b/routine/__pycache__/serializers.cpython-310.pyc differ
diff --git a/routine/__pycache__/urls.cpython-310.pyc b/routine/__pycache__/urls.cpython-310.pyc
index 3b992c7..cbcea1c 100644
Binary files a/routine/__pycache__/urls.cpython-310.pyc and b/routine/__pycache__/urls.cpython-310.pyc differ
diff --git a/routine/__pycache__/views.cpython-310.pyc b/routine/__pycache__/views.cpython-310.pyc
index 7396370..04f0420 100644
Binary files a/routine/__pycache__/views.cpython-310.pyc and b/routine/__pycache__/views.cpython-310.pyc differ
diff --git a/routine/models.py b/routine/models.py
index 255d96c..a0cc211 100644
--- a/routine/models.py
+++ b/routine/models.py
@@ -29,7 +29,7 @@ class Meta:
class RoutineBox(models.Model):
box_id = models.IntegerField(primary_key=True)
- user = models.ForeignKey('User.User', on_delete=models.CASCADE, max_length=11)
+ user = models.ForeignKey('accounts.User', on_delete=models.CASCADE, max_length=11)
routine = models.ForeignKey('Routine', on_delete=models.CASCADE, max_length=11)
class Meta:
diff --git a/routine/serializers.py b/routine/serializers.py
index 430e81e..e71d456 100644
--- a/routine/serializers.py
+++ b/routine/serializers.py
@@ -1,6 +1,7 @@
from rest_framework import serializers
from .models import Routine
from .models import RoutineDetail
+from .models import RoutineBox
class RoutineModifySerializer(serializers.ModelSerializer):
def update(self, instance, validated_data):
@@ -23,25 +24,52 @@ class Meta:
class RoutineSerializer(serializers.ModelSerializer):
class Meta:
model = Routine
- fields = ['routine_name', 'routine_comment', 'routine_day', 'owner_id']
+ fields = ['routine_name', 'routine_comment', 'recommend_count','routine_day', 'owner_id']
class RoutineDetailSerializer(serializers.ModelSerializer):
# def create(self, validated_data):
# instance = RoutineDetail.objects.create(**validated_data)
# return instance
- def update(self, instance, validated_data):
- instance.exercise_id = validated_data.get(' ', instance.exercise_id)
- instance.usebody_id = validated_data.get(' ', instance.usebody_id)
-
class Meta:
model= RoutineDetail
- fields= ['routine', 'exercise', 'usebody', 'day']
+ fields= ['routine', 'day']
+
#뒤에 _id 안붙여도 되나?
+class RoutineDetailCreateSerializer(serializers.ModelSerializer):
+ def update(self, instance, validated_data):
+ instance.exercise_id = validated_data.get(' ', instance.exercise_id)
+ instance.usebody_id = validated_data.get(' ', instance.usebody_id)
+ instance.routine_id = validated_data.get(' ', instance.routine_id)
+ class Meta:
+ model = RoutineDetail
+ fields= ['routine', 'exercise', 'usebody', 'day']
+
class RoutineBoxSerializer(serializers.ModelSerializer):
class Meta:
model= RoutineBox
fields= ['user', 'routine']
+ def create(self, validated_data):
+ user = validated_data['user']
+ routine= validated_data['routine']
+
+ if RoutineBox.objects.filter(user= user, routine=routine).exists():
+ raise serializers.ValidationError("이미 존재하는 루틴입니다.")
+
+ return RoutineBox.objects.create(**validated_data)
+
+class RoutinePopRecommendSerializer(serializers.ModelSerializer):
+ class Meta:
+ model= Routine
+ fields= ['routine_id', 'routine_name', 'routine_comment', 'recommend_count', 'routine_day', 'owner_id']
+
+
+class RoutineSearchSerializer(serializers.ModelSerializer):
+
+ class Meta:
+ model= Routine
+ fields=['routine_name', 'routine_comment', 'owner_id']
+
+
- #request.user.id -> id 만 불러오고
\ No newline at end of file
diff --git a/routine/urls.py b/routine/urls.py
index 90c1654..7ebeb67 100644
--- a/routine/urls.py
+++ b/routine/urls.py
@@ -10,10 +10,14 @@
path('detail/', views.RoutineDetailCreateAPIView.as_view()),
path('detail/check//', views.RoutineDetailCheckAPIView.as_view()),
#path('detail/modify//', views.RoutineDetailModifyAPIView.as_view()),
- path('detail/delete//', views.RoutineDetailDeleteAPIView.as_view()),
+ path('detail/delete/', views.RoutineDetailDeleteAPIView.as_view()),
- path('box//', views.RoutineBoxCreateAPIView.as_view()),
- path('box/check//', views.RoutineBoxCheckAPIView.as_view()),
- path('box/delete//', views.RoutineBoxDeleteAPIView.as_view()),
+ path('box/', views.RoutineBoxCreateAPIView.as_view()),
+ path('box/check/', views.RoutineBoxCheckAPIView.as_view()),
+ path('box/delete/', views.RoutineBoxDeleteAPIView.as_view()),
+ path('recommend/pop/', views.PopularRecommendAPIView.as_view()),
+ path('recommend/follow/', views.FollowRecommendAPIView.as_view()),
+
+ path('search/', views.RoutineSearchAPIView.as_view()),
]
\ No newline at end of file
diff --git a/routine/views.py b/routine/views.py
index dc2f1ad..fed8272 100644
--- a/routine/views.py
+++ b/routine/views.py
@@ -1,5 +1,6 @@
from django.shortcuts import render
+from accounts.utils import login_check
# Create your views here.
from rest_framework.views import APIView
from rest_framework.response import Response
@@ -9,15 +10,21 @@
from routine.models import RoutineDetail
from routine.models import RoutineBox
from usebody.models import Usebody
+from accounts.models import Follow
from routine.serializers import RoutineSerializer
from routine.serializers import RoutinecheckSerializer
from routine.serializers import RoutineModifySerializer
from routine.serializers import RoutineDetailSerializer
from routine.serializers import RoutineBoxSerializer
+from routine.serializers import RoutinePopRecommendSerializer
+from routine.serializers import RoutineSearchSerializer
+from routine.serializers import RoutineDetailCreateSerializer
from django.shortcuts import get_object_or_404
from django.shortcuts import get_list_or_404
+from django.http import JsonResponse
+from django.db import connection
@@ -27,6 +34,9 @@ def post(self,request):
routine_data = {
'routine_name' : request.data.get('routine_name'),
'routine_comment' : request.data.get('routine_comment'),
+ #임시
+ 'recommend_count' : request.data.get('recommend_count'),
+
'routine_day' : request.data.get('routine_day'),
'owner_id' : request.data.get('owner_id'),
}
@@ -39,16 +49,27 @@ def post(self,request):
#내가 담은 루틴 리스트 조회 5-2
class RoutineBoxCheckAPIView(APIView):
- def get(self, request, pk):
- box = get_list_or_404(RoutineBox, user_id=pk)
+ @login_check
+ def get(self, request):
+ box = get_list_or_404(RoutineBox, user_id=request.user.id)
serializer = RoutineBoxSerializer(box, many=True)
return Response(serializer.data)
#내가 담은 루틴 리스트에 추가 5-3
class RoutineBoxCreateAPIView(APIView):
- def post(self, request,pk):
+ @login_check
+ def post(self, request):
+ # box_data = {
+ # 'user_id': request.user.id,
+ # 'routine': request.data.get('routine'),
+ # }
+
+ request.data['user'] = request.user.id
serializer = RoutineBoxSerializer(data=request.data)
+
+
+ #serializer = RoutineBoxSerializer(data=box_data)
#pk를 user_id로 넣고 request로 받은건 routine_id만
if serializer.is_valid():
serializer.save()
@@ -56,9 +77,32 @@ def post(self, request,pk):
return Response(serializer.errors)
#내가 담은 루틴 리스트에서 삭제 5-4
-#class RoutineBoxDeleteAPIView(APIView):
- # def delete(self,request,pk):
+class RoutineBoxDeleteAPIView(APIView):
+ @login_check
+ def post(self,request):
+ request.data['user'] = request.user.id
+
+ f1 = request.data.get('user')
+ f2 = request.data.get('routine')
+
+
+ queryset = RoutineBox.objects.filter(user=f1, routine=f2)
+ temp = queryset
+ deleted_data = {
+ 'message': '삭제 완료',
+ 'deleted_data': temp
+ }
+
+ not_deleted= {
+ 'message' : '해당 루틴이 존재하지 않음'
+ }
+
+ if queryset.exists():
+ queryset.delete()
+ return Response(deleted_data, status=204)
+ else:
+ return Response(not_deleted, status=404)
#루틴 조회 5-5
@@ -73,66 +117,135 @@ def get(self, request,pk):
#루틴 수정 5-6
class RoutinePutAPIView(APIView):
- def get_object(self,pk):
- return get_object_or_404(Routine, pk=pk)
+ @login_check
+ def post(self,request, pk):
+ routine = get_object_or_404(Routine, pk=pk)
- def put(self,request, pk):
- routine = self.get_object(pk)
serializer = RoutineModifySerializer(routine, data=request.data)
+ fail = {
+ "message": "수정 권한이 없습니다."
+ }
+
if serializer.is_valid():
- serializer.save()
- return Response(serializer.data)
+ if request.user.id != routine.owner_id:
+ return Response(fail, status=404)
+ else:
+ serializer.save()
+ return Response(serializer.data)
return Response(serializer.errors, status=400)
#루틴 삭제 5-7
#루틴을 삭제할 때 루틴 세부 정보들도 함께 삭제해야 함
class RoutineDeleteAPIView(APIView):
- def get_object(self,pk):
- return get_object_or_404(Routine, pk=pk)
-
- def get_DetailObject(self, pk):
- return get_list_or_404(RoutineDetail, routine_id=pk)
-
+ @login_check
def delete(self, request, pk):
- routine = self.get_object(pk)
- routineDetail = self.get_DetailObject(pk)
+ routine = get_object_or_404(Routine, pk=pk)
+ routineDetail = RoutineDetail.objects.filter(routine_id=pk)
- #루틴 정보 삭제
- routine.delete()
+ if request.user.id == routine.owner_id:
+ # 루틴 정보 삭제
+ routine.delete()
- #루틴 세부 정보들도 함께 삭제
- for obj in routineDetail:
- obj.delete()
-
- return Response(status=204)
+ # 루틴 세부 정보들도 함께 삭제
+ for obj in routineDetail:
+ obj.delete()
+ success= { "message": "삭제 성공" }
+ return Response(success, status=204)
+ else:
+ fail = { "message": "삭제할 권한이 없습니다."}
+ return Response(fail, status=404)
#루틴 세부사항 생성 5-8
class RoutineDetailCreateAPIView(APIView):
+ @login_check
def post(self, request):
- # 전달되는 값들
+ cursor = connection.cursor()
+ sql = "select owner_id from routine where routine_id = %s"
+ sql2 = "select usebody_id from exercise where exercise_id= %s"
+
+ cursor.execute(sql, [request.data.get('routine')])
+ result = cursor.fetchall()
+
+ cursor.execute(sql2, [request.data.get('exercise')])
+ u_id = cursor.fetchall()
+
+ r = request.data.get('routine')
+ e = request.data.get('exercise')
+ d = request.data.get('day')
+
routineDetail_data = {
- 'routine' : request.data.get('routine'),
- 'exercise': request.data.get('exercise'),
- 'usebody': request.data.get('usebody'),
- 'day': request.data.get('day'),
+ 'routine' : r,
+ 'exercise': e,
+ 'usebody': u_id[0][0],
+ 'day': d,
}
- serializer = RoutineDetailSerializer(data=routineDetail_data)
- if serializer.is_valid():
- serializer.save()
- return Response(serializer.data, status=201)
- return Response(serializer.errors)
+ if result[0][0] == request.user.id:
+ if not RoutineDetail.objects.filter(exercise= e, routine = r, day = d):
+ serializer = RoutineDetailCreateSerializer(data=routineDetail_data)
+
+ if serializer.is_valid():
+ serializer.save()
+ return Response(serializer.data, status=201)
+ return Response(serializer.errors)
+ else:
+ over = {"message": "완전히 중복된 일정입니다."}
+ return Response(over, status = 404)
+ else:
+ NP= {
+ "message": "생성할 권한이 없습니다."
+ }
+ return Response(NP, status=404)
#루틴 세부사항 조회 5-9
class RoutineDetailCheckAPIView(APIView):
def get(self, request,pk):
- routineDetail = get_list_or_404(RoutineDetail, routine_id=pk)
- serializer = RoutineDetailSerializer(routineDetail, many=True)
- return Response(serializer.data)
+ routineDetail = RoutineDetail.objects.filter(routine_id=pk)
+
+ if routineDetail.exists() == False:
+ fail = {
+ "message": "루틴 세부 존재하지 않음"
+ }
+ return Response(fail , status = 404)
+ else:
+ r1, r2, r3 = '', '', ''
+
+ for i in routineDetail:
+ cursor = connection.cursor()
+ sqlR = "select routine_name from routine where routine_id = %s"
+ sqlU = "select usebody_name from usebody where usebody_id = %s"
+ sqlE = "select exerciseName_english from exercise where exercise_id = %s"
+ #한글 번역 너무 구려서 영어로 함
+
+ cursor.execute(sqlR, [i.routine_id])
+ r1 = (cursor.fetchall())[0][0]
+
+ cursor.execute(sqlU, [i.usebody_id])
+ r2 = (cursor.fetchall())[0][0]
+
+ cursor.execute(sqlE, [i.exercise_id])
+ r3 = (cursor.fetchall())[0][0]
+
+ serializer = RoutineDetailSerializer(routineDetail, many=True)
+
+ for i in serializer.data:
+ key1 = f'routine_name'
+ key2 = f'usebody_name'
+ key3 = f'exercise_name'
+
+ value1 = r1
+ value2 = r2
+ value3 = r3
+
+ i[key1] = value1
+ i[key2] = value2
+ i[key3] = value3
+
+ return Response(serializer.data)
#루틴 세부사항 수정 5-10
@@ -153,21 +266,112 @@ def get(self, request,pk):
# 처음부터 url에 루틴 id를 넘겨주고
# 수정 시 해당 루틴에 해당하는 상세사항들만 불러와서
# day 몇을 어떤 운동으로 수정할거냐? 같은 느낌
-#
-# day 몇에 있는 운동을 추가하거나 삭제하는 것.
-# 그것이 생성 또는 삭제를 의미함.
-#
-# 삭제는 해당 루틴에 따른 운동을 모두 삭제한다.
-
#루틴 세부사항 삭제 5-11
class RoutineDetailDeleteAPIView(APIView):
- def delete(self, request,pk):
- routineDetail = get_object_or_404(RoutineDetail, pk= pk)
- routineDetail.delete()
+ @login_check
+ def post(self, request):
+ routine_Detail = RoutineDetail.objects.filter(routine_detail_id= request.data.get('deleteData'))
+
+ #어차피 하나만 검색됨
+ for i in routine_Detail:
+ r_id = i.routine_id
+
+ cursor = connection.cursor()
+ sql = "select owner_id from routine where routine_id = %s"
+ cursor.execute(sql, [r_id])
+ result = cursor.fetchall()
+
+ o_id = result[0][0]
- return Response(status=204)
+ if o_id == request.user.id:
+ routine_Detail.delete()
+ success = {
+ "message": "삭제 성공"
+ }
+ return Response(success, status=204)
+ else:
+ fail = {
+ "message": "삭제 권한 없음"
+ }
+ return Response(fail, status=404)
+#06-01 루틴 추천(팔로잉 중인 유저)
+class FollowRecommendAPIView(APIView):
+ @login_check
+ def get(self, request):
+ user_id = request.user.id
+ objects = get_list_or_404(Follow, follower_id = user_id)
+ matching_ids = [obj.following_id for obj in objects]
+ r_objects= []
+
+ for i in matching_ids:
+ r_objects += list(Routine.objects.filter(owner_id= i))
+
+ serializer = RoutinecheckSerializer(r_objects, many=True)
+
+ return Response(serializer.data)
+
+
+#06-02 루틴 추천(인기순)
+class PopularRecommendAPIView(APIView):
+ def get(self, request):
+ recom = Routine.objects.all().order_by('-recommend_count')
+
+ serializer = RoutinePopRecommendSerializer(recom, many=True)
+
+ return Response(serializer.data)
+
+#07-01 루틴 검색
+#routine_comment, routine_name, owner_id에 대해 검색
+class RoutineSearchAPIView(APIView):
+ def post(self, request):
+ if request.body:
+ # routine_name, comment, id 각각 검사 후 반환
+ objectsName = Routine.objects.filter(routine_name__icontains=request.data.get('searchData'))
+ objectsComment = Routine.objects.filter(routine_comment__icontains=request.data.get('searchData'))
+ objectsId = Routine.objects.filter(owner_id__icontains=request.data.get('searchData'))
+
+ combined_objects = list(objectsName)+ list(objectsComment) + list(objectsId)
+
+ serializer = RoutineSearchSerializer(combined_objects, many=True)
+
+ return Response(serializer.data)
+ else:
+ #검색에 아무것도 안 넣었을 경우 모든 루틴 반환
+ objects = Routine.objects.all()
+ serializer = RoutineSearchSerializer(objects, many=True)
+
+ return Response(serializer.data)
+ #각각 request 3개씩 해놓고 하는 방법
+ # routineSearch_data = {
+ # 'routine_name': request.data.get('routine_name'),
+ # 'routine_comment': request.data.get('routine_comment'),
+ # 'owner_id': request.data.get('owner_id'),
+ # }
+ #
+ # if routineSearch_data['routine_name'] is not None:
+ # objects = Routine.objects.filter(routine_name = routineSearch_data['routine_name'])
+ # else:
+ # objects = Routine.objects.all()
+ #
+ # if routineSearch_data['routine_comment'] is not None:
+ # objects2 = [item for item in objects if item.routine_comment == routineSearch_data['routine_comment']]
+ # else:
+ # objects2 = objects
+ #
+ # if routineSearch_data['owner_id'] is not None:
+ # objects3 = [item for item in objects2 if item.owner_id == routineSearch_data['owner_id']]
+ # else:
+ # objects3 = objects2
+ #
+ # serializer = RoutinecheckSerializer(objects3, many=True)
+ #
+ # #routine_name = routineSearch_data['routine_name']
+ # #이런식으로 접근 할 것
+ # #RoutineSearchSerializer(routineSearch_data, many=true)
+ #
+ # return Response(serializer.data)
diff --git a/usebody/__pycache__/__init__.cpython-311.pyc b/usebody/__pycache__/__init__.cpython-311.pyc
index 011c09e..dfa10ee 100644
Binary files a/usebody/__pycache__/__init__.cpython-311.pyc and b/usebody/__pycache__/__init__.cpython-311.pyc differ
diff --git a/usebody/__pycache__/admin.cpython-311.pyc b/usebody/__pycache__/admin.cpython-311.pyc
index 663961d..8316f7b 100644
Binary files a/usebody/__pycache__/admin.cpython-311.pyc and b/usebody/__pycache__/admin.cpython-311.pyc differ
diff --git a/usebody/__pycache__/apps.cpython-311.pyc b/usebody/__pycache__/apps.cpython-311.pyc
index e8f946e..90a19a8 100644
Binary files a/usebody/__pycache__/apps.cpython-311.pyc and b/usebody/__pycache__/apps.cpython-311.pyc differ
diff --git a/usebody/__pycache__/models.cpython-311.pyc b/usebody/__pycache__/models.cpython-311.pyc
index 8dcfda5..61d865e 100644
Binary files a/usebody/__pycache__/models.cpython-311.pyc and b/usebody/__pycache__/models.cpython-311.pyc differ
diff --git a/usebody/__pycache__/serializers.cpython-311.pyc b/usebody/__pycache__/serializers.cpython-311.pyc
index 8ec2747..4355538 100644
Binary files a/usebody/__pycache__/serializers.cpython-311.pyc and b/usebody/__pycache__/serializers.cpython-311.pyc differ
diff --git a/usebody/__pycache__/urls.cpython-311.pyc b/usebody/__pycache__/urls.cpython-311.pyc
index b8339aa..d50dafe 100644
Binary files a/usebody/__pycache__/urls.cpython-311.pyc and b/usebody/__pycache__/urls.cpython-311.pyc differ
diff --git a/usebody/__pycache__/views.cpython-311.pyc b/usebody/__pycache__/views.cpython-311.pyc
index 2701fca..394c574 100644
Binary files a/usebody/__pycache__/views.cpython-311.pyc and b/usebody/__pycache__/views.cpython-311.pyc differ
diff --git a/usebody/migrations/__pycache__/0001_initial.cpython-311.pyc b/usebody/migrations/__pycache__/0001_initial.cpython-311.pyc
index 3b507b2..ee3a983 100644
Binary files a/usebody/migrations/__pycache__/0001_initial.cpython-311.pyc and b/usebody/migrations/__pycache__/0001_initial.cpython-311.pyc differ
diff --git a/usebody/migrations/__pycache__/__init__.cpython-311.pyc b/usebody/migrations/__pycache__/__init__.cpython-311.pyc
index 3fa9a23..9a43af1 100644
Binary files a/usebody/migrations/__pycache__/__init__.cpython-311.pyc and b/usebody/migrations/__pycache__/__init__.cpython-311.pyc differ