스파르타 코딩클럽
내일배움캠프 AI 웹개발자양성과정 2회차
최종 프로젝트 개발일지
0. 프로젝트 정보
프로젝트 명
MLT - My Little Trip (여행 일정 추천받기)
기간
2022.07.07-08.16
프로젝트 목표
- 서버 배포해보기
- 한번쯤은 다들 필요하다고생각해보는 프로젝트 만들어보기
팀 정보
- 팀명 : 사사십육
- 팀원 : 김동우, 김진수, 최민기, 박진우
역할 분담
- 김동우 : 유저 기능 / 여행일정 추천 기능 + Front 구성
- 김진수 : 여행장소 기능 + server 배포
- 박진우 : 댓글, 좋아요 기능 + server 배포
- 최민기 : 리뷰 기능 + server 배포
Base 추천알고리즘 github
Frontend github
1. Place 기능
1) Place Model
# 장소 타입 모델
class PlaceType(models.Model):
typename = models.CharField("장소 유형", max_length=100, unique=True)
def __str__(self):
return self.typename
# 장소 모델
class Place(models.Model):
_id = models.BigIntegerField("장소 id", unique=True)
user = models.ForeignKey(User, verbose_name="등록자",
on_delete=models.CASCADE)
placetype = models.ForeignKey(
PlaceType, verbose_name="장소 유형", on_delete=models.CASCADE)
name = models.CharField("장소 이름", max_length=100)
word = models.CharField("검색단어", max_length=100)
address = models.CharField("주소", max_length=100)
x = models.CharField("x좌표(경도)", max_length=50)
y = models.CharField("y좌표(위도)", max_length=50)
image = models.ImageField(
'장소 이미지', upload_to="static/images/place/%Y%m%d", null=True)
rating = models.FloatField(
"평점", validators=[MinValueValidator(0.0), MaxValueValidator(5.0)], default=0.0)
description = models.TextField("설명", null=True)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("place_detailview", kwargs={"place_id": self.pk})
# 이동시간 모델
class Duration(models.Model):
start_id = models.BigIntegerField("출발지 장소 id")
start_place = models.ForeignKey(
Place, verbose_name="출발지", on_delete=models.CASCADE, related_name="start_place")
end_id = models.BigIntegerField("도착지 장소 id")
end_place = models.ForeignKey(
Place, verbose_name="도착지", on_delete=models.CASCADE, related_name="end_place")
duration = models.IntegerField("이동시간")
def __str__(self):
return f"{self.start_place.name} - {self.end_place.name} : {self.duration}"
2) Place Serializer
# place/serializers.py
from rest_framework import serializers
from place.models import Place, PlaceType
from user.models import User
from user.serializers import UserSerializer
class PlaceDetailSerializer(serializers.ModelSerializer):
class Meta:
model = Place
fields = ['_id','user','word','placetype','name','address','x','y','image','rating','description']
class PlaceTypeSerializer(serializers.ModelSerializer):
class Meta:
model = PlaceType
fields = ['id', 'typename']
class PlaceSerializer(serializers.ModelSerializer):
user = serializers.SerializerMethodField(read_only=True)
placetype = serializers.SerializerMethodField(read_only=True)
def get_user(self, obj):
return obj.user.username
def get_placetype(self, obj):
return obj.placetype.typename
class Meta:
model = Place
fields = [
'id',
'user',
'placetype',
'name',
'word',
'address',
'x',
'y',
'image',
'rating',
'description'
]
class PlaceAddSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
placetype = serializers.SerializerMethodField()
def get_placetype(self, obj):
return obj.placetype.typename
def create(self, validated_data):
place = Place(**validated_data)
place.save()
return place
class Meta:
model = Place
fields = [
'id',
'user',
'placetype',
'name',
'address',
'x',
'y',
'image',
'description',
'_id',
'word'
]
class PlaceUpdateSerializer(serializers.ModelSerializer):
user = UserSerializer(read_only=True)
placetype = serializers.SerializerMethodField()
def get_placetype(self, obj):
return obj.placetype.typename
class Meta:
model = Place
fields = [
'id',
'user',
'placetype',
'name',
'address',
'x',
'y',
'image',
'description',
'_id'
]
3) Place View
# place/views.py
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from place.serializers import PlaceSerializer, PlaceAddSerializer, PlaceUpdateSerializer,PlaceDetailSerializer
from .models import Place, PlaceType
from user.models import User
from rest_framework_simplejwt.authentication import JWTAuthentication
# Create your views here.
# 장소 상세 조회
class PlaceViewDetail(APIView):
def get(self,request,place_id):
detailplaces = Place.objects.get(id=place_id)
return Response(PlaceDetailSerializer(detailplaces).data, status=status.HTTP_200_OK)
class PlaceViewAll(APIView):
authentication_classes = [JWTAuthentication] #JWT 인증
# 장소 모두 조회
def get(self, request):
allplaces = Place.objects.all()
return Response(PlaceSerializer(allplaces, many=True).data, status=status.HTTP_200_OK)
# 장소 등록
def post(self, request):
if not request.user.is_authenticated:
return Response({"message": "로그인해주세요"}, status=status.HTTP_401_UNAUTHORIZED)
request.data['rating'] = 0
image = request.FILES.get("image", "")
placetype_typename = request.data.pop('placetype', '')[0]
placetype_object = PlaceType.objects.get(typename=placetype_typename)
user_id = request.data.pop('user', '')[0]
user_object = User.objects.get(id=user_id)
placeadd_serializer = PlaceAddSerializer(data=request.data)
if placeadd_serializer.is_valid():
placeadd_serializer.save(user=user_object,placetype=placetype_object,image=image)
return Response(placeadd_serializer.data, status=status.HTTP_200_OK)
return Response(placeadd_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# 장소 수정
def put(self, request, place_id):
place = Place.objects.get(id=place_id)
place_serializer = PlaceUpdateSerializer(place,data=request.data,partial=True)
if place_serializer.is_valid():
place_serializer.save()
return Response({"message": "정상"}, status=status.HTTP_200_OK)
return Response(place_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#장소 삭제
def delete(self, request, place_id):
place = Place.objects.get(id=place_id)
place.delete()
return Response({"msg":"삭제완료"})
2. 도커를 통한 서버 배포
3. 기타 정보
1) 프로젝트 문서
https://www.notion.so/kimphysicsman/MLT-My-Little-Trip-716433a2fc8940d9870bd83b63570646
2) github
https://github.com/nbcamp-AI-2-fantastic4/MyLittelTrip_backend
https://github.com/nbcamp-AI-2-fantastic4/MyLittelTrip_frontend_react
'포트폴리오' 카테고리의 다른 글
내일배움캠프 - My Little Shoes 개발일지 (0) | 2022.08.22 |
---|