2022. 1. 5. 15:41ㆍ작업/Django
프론트 분들과 논의한 페이지 와이어프레임(피그마)
yarn react사용하심 백엔드는 장고 사용
유의점
- 영화제목 + 게시물글 제목 + 장르 2개까지 검색 가능하나 AND기능은 불가능합니다(영화제목이 마블 이면서 장르가 액션인 게시글 보여주지 못함 -> 그러나 어차피 검색을 더 큰범위에서 다 보여주니까 이런 작은 프로젝트에서는 크게 상관은 없다 나중에 추가구현 해보기)
DB내용
파일구조 backend/Django 프로젝트
서버 실행
전체 리스트 /small-theater
상세페이지 small-theater/2
(small-theater2 로 들어가게 구현할 수도 있음 그러려면 small_theeater/urls.py에서 /뺴면 됨)
장르가 로맨스인 게시물 검색 small-theater?search-genre1=로맨스
장르에 로맨스 또는 액션이 들어간 게시물 모두 검색 small-theater?search-genre1=로맨스&search-genre2=액션
장르에 로맨스 또는 액션이 들어간 영화 + 소극장제목이 마블 인 게시물 모두 검색
small-theater?search-genre1=로맨스&search-genre2=액션&title=마블
소극장 제목만 검색(소극장 제목이 마블인 게시물 검색) small-theater?title=마블
이렇게 제목 끝까지 안쳐도 나온다.
장르 하나만 검색할 때 small-theater?search-genre2=공포로 해도 됩니다.
코드
views.py
from django.http import response, JsonResponse, HttpResponse #안씀
from django.shortcuts import render #안씀
from django.views import generic #안씀
from django.db.models import Q #filter시 | 사용하려고
from urllib import parse #한글 인코딩
from rest_framework.views import APIView #CBV
from rest_framework import status,generics #200 404 등 , ListAPIView
from rest_framework.response import Response
# from rest_framework.decorators import api_view # @api_view FBV
from .models import SmallTheater
from .serializers import SmallTheaterSerializer
# FBV와 Generic View가 있음
# FBV는 세세하게 코딩/ Generic view는 간편 -> 섞어도 됨
# POST,GET 둘다 요청
# POST은 뭔가 sideeffect가 있을 때(바뀌거나 넣어줘야 할 때) GET은 응답(데이터)만 주면 될 때
# CBV POST,GET,DELETE,UPDATE 참고사이트
# https://toughbear.tistory.com/60
# **kwargs https://d-yong.tistory.com/61
# 공식문서 https://www.django-rest-framework.org/tutorial/3-class-based-views/
# 쿼리셋 <-> JSON https://www.delftstack.com/ko/howto/django/django-queryset-to-json/
# static, 템플릿 등 참고사이트 https://iamiet.tistory.com/10?category=928115
# api 요청 이용해 drf <-> 리엑트 연동 https://this-programmer.tistory.com/135
# 쿼리셋 all order_by filter 사용법 https://velog.io/@swhybein/django-queryset
# Create your views here.
# 쿼리셋 filter, ordering 일본개발자 블로그 https://freez2385.github.io/posts/Python-Django-django_restframework2/
# filtering, ordering 블로그2 https://donis-note.medium.com/django-rest-framework-filtering%EA%B3%BC-ordering-4e7d1351205a
# 딕셔너리 .get, .items() 등등 https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=sw4r&logNo=221504133335
# 한글인코드 https://dololak.tistory.com/255
# 1.
# class SmallTheaterList(APIView): # 소극장 전체 보기는 구현완료
# def get(self,request,**kwargs): # http://localhost/small-theater?search_genre1=romance&search_genre2=romance&title=마블
# small_theater_list = SmallTheater.objects.all() #쿼리에 따라 DB에 있는 소극장 목록 가져오기
# small_theater_serializer = SmallTheaterSerializer(small_theater_list,many=True)
# return Response(small_theater_serializer.data,status=status.HTTP_200_OK)
# 2.
class SmallTheaterList(APIView): # 소극장 목록 보기
# http://127.0.0.1:8000/small-theater?search-genre1=드라마&search-genre2=공포&title=마블
def get(self,request,**kwargs):
search_genre1 = request.GET.get('search-genre1')
search_genre2 = request.GET.get('search-genre2')
search_title =request.GET.get('title')
for key in request.GET.keys():
if request.GET.get(key)!=None:
parse.unquote(request.GET.get(key)) #None이 아니면 한글로 바꿔라
# 1. genre1,genre2,title 셋 다 None인 경우
if (search_genre1==None) & (search_genre2==None) & (search_title==None):
final_queryset = SmallTheater.objects.all().order_by('-published_date') # /small-theater
# 2. title이 있는 경우(__contains오류 떄문에 얘만 따로)
elif search_title:
queryset = SmallTheater.objects.filter(Q(theater_genre1=search_genre1) | Q(theater_genre2=search_genre1) | Q(theater_genre1=search_genre2) | Q(theater_genre2=search_genre2) | Q(title__contains=search_title)) #단어포함 title__contains = 어쩌구
final_queryset = queryset.order_by('-published_date') #published_date하면 오름차순
# 3. genre1,genre2,title 중 하나라도 있는 경우
else:
queryset = SmallTheater.objects.filter(Q(theater_genre1=search_genre1) | Q(theater_genre2=search_genre1) | Q(theater_genre1=search_genre2) | Q(theater_genre2=search_genre2) | Q(title=search_title)) #단어포함 title__contains = 어쩌구
final_queryset = queryset.order_by('-published_date')
target_theater_serializer = SmallTheaterSerializer(final_queryset, many=True)
return Response(target_theater_serializer.data, status=status.HTTP_200_OK)
class SmallTheaterDetail(APIView): # 소극장 상세보기
# http://127.0.0.1:8000/small-theater/3
def get(self,request,**kwargs): #http://localhost:8000/small-theater/{small_theater.id}
target_theater_id = kwargs.get('id') # 4 (int)
queryset = SmallTheater.objects.filter(id=target_theater_id) # get은 하나만 가져옴 not iterable이슈 있음
target_theater_serializer = SmallTheaterSerializer(queryset, many=True)
return Response(target_theater_serializer.data, status=status.HTTP_200_OK)
models.py
from django.db import models
# 필터링 및 검색기능 참고사이트 https://fierycoding.tistory.com/67
# Create your models here.
class SmallTheater(models.Model):
# no = models.AutoField(primary_key=True)
published_date = models.DateField()
title = models.CharField(max_length=200, default='')
theater_owner = models.CharField(max_length=10, null=True) # 우리는 소극장생성은 안하고 가상의 유저들이 있다치고 보여줄 거니까 아마 user랑 연결될 필요 없다고 생각! 단순 Char로 가상의 유저1,유저2,유저3들의 닉네임만 넣어주자
theater_genre1 = models.CharField(max_length=30, null=True) # 'action' / default=''할까
theater_genre2 = models.CharField(max_length=30, null=True) # 'romance'
# 이것도 우리끼리 정의한 호러=1, 로맨스=2, 액션=3 이렇게? 총 1,2,3,4,5,6,7,8 몇 까지 있는 걸까?
# -> 어차피 소극장 목록에서 액션/로맨스 로만 보여줄거니까 일단 검색 편하게 Char로
introduce = models.CharField(max_length=1000, null=True)
notice = models.CharField(max_length=1000, null=True)
class Meta:
# managed = False # 자동 migration
db_table = 'small_theater'
small_theater/urls.py
from django.conf.urls import url, include
from django.urls import path
from . import views #small_theater/views.py
from django.conf import settings
from django.conf.urls.static import static
app_name = 'small_theater'
urlpatterns =[
path('', views.SmallTheaterList.as_view()),
path('/<int:id>',views.SmallTheaterDetail.as_view()) # http://127.0.0.1:8000/small-theater/4 앞에 슬래시 없애면 small-theater4로 들어감
]
serializers.py
# serializer : 객체처럼 보기힘든 데이터를 JSON이나 XML으로 보기쉽게 데이터 바꿔줌
# REST API : Resource 이름가지고 클라이언트와 서버가 통신하는 방법 만들 때 필수적임
# 주의! 장고 서버와 REST 서버는 따로 운영되어야 한다!!
from rest_framework import serializers
from .models import SmallTheater
# 리엑트연동까지 https://this-programmer.tistory.com/135
# Serializer 자세한 설명 https://brownbears.tistory.com/71
class SmallTheaterSerializer(serializers.ModelSerializer):
class Meta:
model = SmallTheater # models.py속 모델
fields = ('__all__') # 통신할 데이터필드 -> 모든 필드 하려면 '__all__'해도 됨
# fields = ('id','published_date'...,)
'작업 > Django' 카테고리의 다른 글
22.01.07 소극장 파트 드디어 마무리!! (0) | 2022.01.07 |
---|---|
22.01.03 아부지 생일 ㅋㅋ 및 리엑트설치 & 장고랑 연동해보기 (0) | 2022.01.03 |
22.01.02 FBV와 CBV가 뭘까 / django-cors-headers / serializer 공부 (0) | 2022.01.03 |
22.01.02 backend/user/seoyoon models.py 작업 시작 (0) | 2022.01.02 |
21.12.27 MySQL과 WSL2 Django와 연동하기 / MySQL 계정 생성,접속,삭제 (0) | 2021.12.28 |