F 표현식을 사용했을 때의 쿼리 변화에 대해 알아보자
F expressions
F() 개체는 모델 필드의 값, 모델 필드의 변환된 값 또는 주석이 달린 열을 나타냅니다. 모델 필드 값을 참조하고 실제로 데이터베이스에서 Python 메모리로 가져오지 않고도 이를 사용하여 데이터베이스 작업을 수행할 수 있습니다.
https://docs.djangoproject.com/en/4.1/ref/models/expressions/#f-expressions
Text 수정
- 일반적인 경우
할일의 타이틀 값을 가져와서 "쿼리테스트라니깐" 문구를 더하고 더한 값으로 수정한다(덮어씌우듯이).todo = Todo.objects.get(content="쿠우") todo.title = todo.title + "쿼리테스트라니깐" todo.save()
- F expressions
할일의 타이틀이 뭔지 모르겠지만 할일의 타이틀에 "쿼리테스트라니깐" 문구를 DB에서 더한다.todo = Todo.objects.get(content="쿠우") todo.title = F("title") + "쿼리테스트라니깐" todo.save()
- 변경 결과
하지만 Text의 경우(여기서는models.CharField
) F expressions 연산이 제대로 반영되지 않는다.
Interger 수정
: Integer의 경우 F expressions 연산이 제대로 반영된다.
todo = Todo.objects.get(content="쿠우") todo.title = F("rating") + 5 todo.save()
todo = Todo.objects.get(content="쿠우") todo.rating = F("rating") + F("title") todo.save()
update()
: 위에서 값을 수정하기위해 2번씩 반복되는 쿼리를 하나로 줄일 수 있다.
todo_list = Todo.objects.all() todo_list.update(rating=F("rating") + 5)
- 쿼리 필터에서 동일한 모델의 다른 필드값과 비교하기위해 사용가능하다
todo_list = Todo.objects.filter(due_date__lt=F('created_at')).select_related("user") for todo in todo_list: print(todo)
- date and date/time 필드인 경우 timedelta 개체와 연산이 가능하다.
todo_list = Todo.objects.filter(due_date__lt=F('created_at')+timedelta(days=3)).select_related("user") for todo in todo_list: print(todo)
- 그외 비트연산도 가능하다
.bitand()
,.bitor()
,.bitxor()
,.bitrightshift()
,.bitleftshift()
F('somefield').bitand(16)