카테고리 없음

MOVIEBATTLE 소스

황성안 2021. 6. 25. 13:09
728x90
반응형

MovieBettle

 

설계 및 구현

 

1. 로그인, 회원가입

관리자 설정을 위하여 admin.py를 코딩해줍니다.

community > admin.py

from django.contrib import admin
from .models import Community, Movie

admin.site.register(Movie)
admin.site.register(Community)

 

유저들의 로그인 정보보를 api 로 받아 인증과 비인증 처리를 해줍니다.

로그인

api token auth 를 이용하여 인증 키값을 주고받으며 인증확인을 합니다.

회원가입

signup 이라는 친구를 만들어 회원가입이 작동합니다.

community > urls.py

from django.urls import path
from . import views
from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
    path('signup/', views.signup),
    path('api-token-auth/', obtain_jwt_token),

]

community > views.py

from django.shortcuts import render

# Create your views here.
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response

from .serializers import *

@api_view(['POST'])
def signup(request):
    # 1. 사용자한테 아이디, 비밀번호를 받아서
    # username = request.data.get('username')
    password = request.data.get('password')
    password_confirmation = request.data.get('password_confirmation')

    if password != password_confirmation:
        return Response(status=status.HTTP_400_BAD_REQUEST)
    # 2. (바인딩 후 ) 유효성 검사를 하고
    serializer = UserCreationSerializer(data=request.data)
    if serializer.is_valid(raise_exception=True):
        # 3. 저장(== 회원가입)
        user = serializer.save()
        user.set_password(request.data.get('password'))
        user.save()
        return Response(data=serializer.data)

 

community > serializers.py

extra_kwargs는 password를 절떄 외부에 보여주면 안되기떄문에 writeonly 를 하기위해 추가한다.

Userserializers를 통해서 view와 연결하려고 만듭니다!

from rest_framework import serializers
from django.contrib.auth import get_user_model

from community.serializers import *
from community.models import *

User = get_user_model()

class UserCreationSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = ('username', 'password' )
        extra_kwargs = {'password': {'write_only': True}}

class UserSerializer(serializers.ModelSerializer):
    community_set = CommunitySerializer(many=True)
    vote_movie = MovieSerializer(many=True)
    class Meta:
        model = User
        fields = ['id', 'username', 'community_set', 'vote_movie',]

 

2. 투표 기능

인스타나 페이스북의 좋아요 버튼에서 착안하여 만들게됐습니다.

accounts > models.py

# from django.db import models
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.conf import settings

# Create your models here.
class User(AbstractUser):
    vote_movie = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='vote_users')

 

 

 

3. 페이지 기능

3-1. urls.py

프로필을 볼수있는 기능

전체 영화 리스트를 볼수 있는 기능

전체 게시글을 볼수 있는 기능

게시글 한개를 볼수 있는 기능 ( 안에 삭제, 수정 등의 기능 포함)

게시글 만들수 있는 기능

나의 게시글 보기 기능

내가 투표하는 기능

댓글 달기 기능

댓글 추가 삭제 기능

최대 투표량을 가진 게시글 찾기 기능

from django.urls import path
from . import views

urlpatterns = [
    # todo list
    path('profile/<int:user_pk>/', views.profile),
    # GET http://localhost:8000/api/v1/community/
    path('movie_list/', views.movie_list),
    path('post_list/', views.post_list),

    # GET, POST, PUT, DELETE http://localhost:8000/api/v1/community/:id/
    path('post_detail/<int:post_id>/', views.post_detail),
    # test
    # path('json-1/', views.community_json_1),
    path('post_create/', views.post_create),
    path('my_post/', views.my_post, name='my_post'),
    path('my_vote/<int:movie_pk>/', views.my_vote, name='my_vote'),
    #comment
    path('commentcreate/<int:post_id>/', views.commentcreate),
    path('comment_update_and_delete/<int:comment_pk>/', views.comment_update_and_delete),

    # 최대 투표 포스트 찾기
    path('recommand/', views.recommand),
]

3-2. views.py

url.py 의 순서와 동일합니다.

#PEP8 이라는 파이썬 암묵적 준수하는 스타일 가이드가 있다.
#내장 모듈

#외부 라이브러리
from django.shortcuts import get_object_or_404
# import community
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response

#장고
from django.shortcuts import get_object_or_404
from django.contrib.auth import get_user_model


#커스텀 파일 or 로컬 파일
from .serializers import *
from .models import *
from accounts.serializers import *
from accounts.models import *
# from community import serializers
User = get_user_model()


# Create your views here.
@api_view(['POST'])
def post_create(request):
    movie1_title = request.data.get('movie_title_1')
    movie2_title = request.data.get('movie_title_2')
    movie1 = Movie.objects.get(title=movie1_title)
    movie2 = Movie.objects.get(title=movie2_title)
    print(request.data)
    if request.user.is_authenticated:
        # print()
        if request.method == 'POST':
            serializer = CommunitySerializer(data = request.data)
            # print(serializer)
            if serializer.is_valid(raise_exception=True):
                serializer.save(user=request.user, movie_title_1=movie1, movie_title_2=movie2)
                return Response(serializer.data)
        return Response(status=400)
    return Response(status=400)


#무비 리스트 불러오기
@api_view(['GET', 'POST'])
def movie_list(request):
    if request.method == 'GET':
        movies= Movie.objects.all()
        serializer = MovieSerializer(movies, many=True)
        return Response(serializer.data)
    # elif request.method == 'POST':
    #     serializer = CommunitySerializer(data=request.data) # 바인딩
    #     if serializer.is_valid(raise_exception=True):
    #         serializer.save(author=request.user)
    #         return Response(data=serializer.data, status=status.HTTP_201_CREATED)


#게시글 리스트 불러오기
@api_view(['GET', 'POST'])
def post_list(request):
    if request.method == 'GET':
        posts= Community.objects.all()
        serializer = CommunitySerializer(posts, many=True)
        return Response(serializer.data)
    elif request.method == 'POST':
        serializer = CommunitySerializer(data=request.data) # 바인딩
        if serializer.is_valid(raise_exception=True):
            serializer.save(author=request.user)
            return Response(data=serializer.data, status=status.HTTP_201_CREATED)


@api_view(['GET', 'PUT', 'DELETE'])
def post_detail(request, post_id):
    post = get_object_or_404(Community, pk=post_id)
    if request.method == 'GET':
        serializer = CommunitySerializer(post)
        return Response(data=serializer.data)

    elif request.method == 'PUT':
        # 바인딩
        serializer = CommunitySerializer(
                data=request.data, instance=post
                )
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(data=serializer.data)

    elif request.method == 'DELETE':
        post.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


@api_view(['GET', 'PUT', 'POST', 'DELETE'])
def my_vote(request, movie_pk):
    movie = get_object_or_404(Movie, pk=movie_pk)
    if request.method == 'GET':
        serializer = MovieSerializer(movie)
        return Response(serializer.data)
    elif request.method == 'PUT':
        serializer = VoteSerializer(data=request.data, instance=movie)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response(serializer.data)
    elif request.method == 'POST':
        print(request.user)
        print(request.user.id)
        print('여기')
        movie.vote_users.add(request.user.id)
        serializer = MovieSerializer(data=request.data)
        # print(serializer.data) 
        # console.log(serializer)
        if serializer.is_valid(raise_exception=True):
            print('제발')
            serializer.save(vote_users=request.user.id)
        return Response(data=serializer.data)
    else:
        movie.vote_users.remove(request.user)
        return Response(status=status.HTTP_204_NO_CONTENT)


#내가 적은 글(?), 투표한 글
@api_view(['GET'])
def my_post(request):
    print(request.data)
    user = request.user
    user_serializer = UserSerializer(user)
    return Response(user_serializer.data)


#프로필
@api_view(['GET'])
def profile(request, user_pk):
    user = get_object_or_404(get_user_model(), pk=user_pk)
    user_serializer = UserSerializer(user)
    return Response(user_serializer.data)


@api_view(['POST'])
def commentcreate(request, post_id):
    serializer = CommentSerializer(data=request.data)
    user_id = request.data.get('user_id')
    if serializer.is_valid(raise_exception=True):
        serializer.save(post_id=post_id, user_id=user_id)
    return Response(serializer.data)


@api_view(['PUT', 'DELETE'])
def comment_update_and_delete(request, comment_pk):
    comment = get_object_or_404(Comment, pk=comment_pk)
    if request.method == 'PUT':
        serializer = CommentSerializer(data=request.data, instance=comment)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            return Response({'message': '댓글 수정 완료'})
    else:
        comment.delete()
        return Response({'message': '댓글 삭제 완료'})


@api_view(['GET'])
def recommand(request):
    vote_max = 0
    post_info = {}
    # 하나의 게시글에 두개의 영화 ,
    for post in Community.objects.all():
        print(post)
        # rank_post = Community.objects.get(pk=posts)
        
        movie1 = post.movie_title_1.vote_users.count()
        movie2 = post.movie_title_2.vote_users.count()
        result = movie1+movie2

        if result > vote_max:
            vote_max = result
            post_info = post
    print(vote_max)
    serializer = CommunitySerializer(post_info)
    return Response(data = serializer.data)

        # return print(result)
    
        #저 vote_max를 나오게한 영화를 역으로 추적하는 방법은?
        # 커뮤니티에 sumvote model을 만들어줘야하나?

 

 

4. 사용모듈

  • Django, python
  • SQLite3
  • POSTMAN

 

728x90
반응형