지난번 모델을 수정하면서 몇가지 문제점이 드러났다.
class Question(CommonModel):
description = models.TextField()
class Meta:
abstract = True
# 공용 질문
class Questions(Question):
authon = models.ForeignKey(
"users.User",
on_delete=models.CASCADE,
)
count = models.PositiveIntegerField(default=1)
# 개인 질문 모음
class SellectedQuestions(Question):
user = models.ForeignKey(
"users.User",
on_delete=models.CASCADE,
)
importance = models.PositiveIntegerField(default=3)
Question을 공통으로 상속을 받으니까 ForeignKey를 따로 사용 안해도 된다고 생각했는데. 다른 유저들이 얼마나 선택했는지 알려주는 count의 값을 세기 위해서는 ForeignKey가 필요했다.
데이터베이스를 삭제하고 다시 하는것이 편하겠지만, 실제 상황에서는 할 수 없는 방법이므로 기존의 데이터를 유지하면서 필드를 추가하는 방법에 대해서 고민을 해 보았다.
새롭게 필드를 추가한 후
class SellectedQuestions(Question):
user = models.ForeignKey(
"users.User",
on_delete=models.CASCADE,
)
importance = models.PositiveIntegerField(default=3)
question = models.ForeignKey(
"Questions",
on_delete=models.SET_NULL,
null=True,
blank=True, # 나중에 삭제
related_name="questions_set",
)
blank=True를 넣어서 빈칸으로 마이그레이션을 가능하도록 한다.
그러면 현재 question은 빈 값이다.
그리고 question에 값을 넣어줄 함수를 구현한다. (SQL문이 아니라 ORM을 활용한 이유는 for문을 돌리고 싶어서 입니다.)
class ConnectQuestion(APIView):
@transaction.atomic(using="default")
def get(self, request):
if request.user.is_staff == True:
try:
with transaction.atomic():
sellected_questions = SellectedQuestions.objects.all()
for sq in sellected_questions:
qs = Questions.objects.filter(description=sq.description)
# 1 값 넣어줌
if len(qs) == 1:
sq.question = qs[0]
# 2 없으면 None
elif len(qs) == 0:
sq.question = None
# 3 중복되면 에러 발생(롤백한다. )
else:
raise ParseError
sq.save()
return Response(status.HTTP_200_OK)
except:
pass
return Response(
{"message": "작업도중 에러 발생"}, status=status.HTTP_400_BAD_REQUEST
)
return Response({"message": "스태프가 아님"}, status=status.HTTP_403_FORBIDDEN)
1. views_admin.py이라는 새로운 페이지를 만들어 주었고
2. if_staff 권한이 있는 사람만 작동 가능하도록 설정을 해 주었다.
3. 트랜잭션을 사용하여 #3 description 가 중복되었을 시 일단 작업을 취소 하도록 만들었다.
url
urlpatterns = [
......
......
# admin
path("admin", views_admin.ConnectQuestion.as_view()),
]
테스트 결과 이상 무~~~
원래 계획은 count도 변화를 주는 것이었는데. 막상 테스트를 해 보니까 count를 기준으로 정렬을 하고 있는데. 여기에 문제가 생겨서 count는 그대로 두기로 한다.
이제 수정과 관련된 기능만 수정한 다음 배포된 서버에 등록하면 된다.
로컬에서 서버용 MySQL을 연결해 준 다음 마이그레이션을 해 주고
서버 백엔드 서버에 들어가 함수를 실행 시켜주어서 완료~
다행히 오류는 다 해결이 된거 같다~