TIL#128 Review (1)

Dasom·2021년 1월 31일
0

Django

목록 보기
20/33

이번주는 새로운 과제를 진행하였다. Django+jQuery 를 사용해 게시판 만들기!
목요일에 첫 리뷰가 있었고 주말동안 리팩토링을 할 예정이다.
공부해야 할 것이 많기 때문에 정리하면서 공부할 예정 :)

리뷰 받은 것들을 리뷰가 끝나고 해야 할 것들을 다시 한번 정리했고 적용중이다 :)

annotate

annotate 는 쿼리셋에서 임시로 컬럼을 생성해주는 메서드이다.

# 과제 중인 모델의 일부분을 가져와 보았다

# boards/models.py
class Posting(models.Model):
    user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.SET_NULL, related_name='postings', null=True)
    title = models.CharField(_('제목'), max_length=50)
    content = models.TextField(_('내용'))
    
# users/models.py
class User(AbstractUser):
    name = models.CharField(_('이름'), max_length=20)

모델에서 작성자, 제목, 내용을 가져오려고 한다.

>>> Posting.objects.filter(user__name='고양이').values('title','content','user__name')
<QuerySet [{'title': 'dsafdasf', 'content': 'asfadsfasfadsf', 'user__name': '고양이'}, 
	   {'title': 'fasfasdfa', 'content': 'fdasfdsafasfda', 'user__name': '고양이'}, 
	   {'title': 'siafdasfdasfdasf', 'content': 'dasfdasfdsafd', 'user__name': '고양이'}]>

user는 ForeignKey로 연결되어 있기 때문에 컬럼값을 가져오려면 user__name 이 키값이 되어 버린다. 키값을 바꾸고 싶다면 annotate를 이용해 임시 컬럼을 생성하면 된다.

>>> Posting.objects.filter(user__name='고양이').annotate(name=F('user__name')).values('title','content','name')
<QuerySet [{'title': 'dsafdasf', 'content': 'asfadsfasfadsf', 'name': '고양이'}, 
	   {'title': 'fasfasdfa', 'content': 'fdasfdsafasfda', 'name': '고양이'}, 
	   {'title': 'siafdasfdasfdasf', 'content': 'dasfdasfdsafd', 'name': '고양이'}]>

get_or_create

get_or_create 메서드는 말 그래도 가져오거나 생성하는 메서드이다. (object, created) 의 튜플 형식으로 반환된다. 첫번째 인자는 꺼내려고 하는 모델의 인스턴스이고 두번째 인자는 boolean flag 이다.

  • 두번째 인자가 True 인 경우
    : 존재하지 않아서 새로 생성되었다는 것을 의미
  • 두번째 인자가 False 인 경우
    : 존재하여서 get으로 객체를 가져왔음을 의미

F

F() 객체는 모델 필드의 값을 나타낸다. 데이터베이스에서 파이썬 메모리로 데이터를 가져오지 않고 모델의 필드값을 참조하여 데이터베이스 작업을 수행할 수 있다.

# 과제의 일부분 / review 전

# boards/views.py
class PostingDetailView(LoginRequiredMixin, DetailView):
	(생략)
    def get_context_data(self, **kwargs):
        posting = Posting.objects.get(id=self.kwargs.get('posting_id'))
        posting.views += 1
        posting.save()

리뷰 때 F() 를 공부해보고 적용해 보라고 피드백을 주셨다. 예전 프로젝트 당시에 한번 써보았던 게 전부이다 보니 응용을 못하였던 것 같다. 그래서 다시 공부를 하였다 :)

  • python 이 아닌 데이터베이스에서 해당 연산을 처리한다
  • 몇몇 작업에서는 필요한 쿼리의 수를 줄일 수 있다
  • race condition을 피할 수 있다
  • annotation, 필터링, 정렬에 효과적으로 사용할 수 있다
# 과제의 일부분 / review 후 

# boards/views.py
class PostingDetailView(LoginRequiredMixin, DetailView):
	(생략)
    def get_context_data(self, **kwargs):
        posting = Posting.objects.get(id=self.kwargs.get('posting_id'))
        posting.views = F('views') + 1
        posting.save()

related_name을 설정해 주지 않아도 검색할 수는 있다. 하지만 굳이 related_name 속성을 정의해주는 이유는 간혹 두 모델 사이에 ForeignKey가 두개 이상 존재하는 경우가 있다. 이 때 자동 생성된 related_name이 겹쳐서 오류가 생길 수 있기 때문에 습관적으로 related_name을 추가해주면 오류를 줄일 수 있다.

profile
개발자꿈나무🌲

0개의 댓글