django.db.models.Q 객체는 get(), exclude(), filter()와 같은
키워드 인자를 전달받을 수 있는 django query 메소드의 인자를
캡슐화하여 좀 더 복잡한 query를 만드는 데 사용하는 객체이다
예를 들면 WHERE문에서의 AND, OR 조건과 조건에 대한 NOT 연산 등을
적용할 수 있다
AND
Q(questionstartswith='Who') & Q(questionstartswith='What')
Q(questionstartswith='Who'), Q(questionstartswith='What')
OR
Q(questionstartswith='Who') | Q(questionstartswith='What')
NOT
~Q(question__startswith='Who')
Q객체의 리턴값은 위치인자이지만 키워드 인자처럼 동작한다
그렇기 때문에
Poll.objects.get(
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
question__startswith='Who',
) # 이 코드는 제대로 동작하지만
Poll.objects.get(
question__startswith='Who',
Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
) # 이 코드는 syntax error가 발생한다
django.db.models.F 객체는 모델의 속성값에 대한 maneuver를
python 메모리로 캐시하지 않고 DB에서 처리할 때 사용하는 객체이다
reporter = Reporters.objects.get(name='Tintin')
reporter.stories_filed = F('stories_filed') + 1
reporter.save()
django는 F() 인스턴스를 만나면 뒤에 이어지는 python operator를
override하여 F('stories_filed') + 1 자체를 query한다
그렇기 때문에 python은 reporter.stories_filed의 값을 fetch해오지 않아
값을 알수 없다
F 객체를 사용하여 DB의 값을 직접 조정하였을 경우
다음과 같은 방법으로 model객체를 리로드 해야한다
reporter = Reporters.objects.get(pk=reporter.pk)
# or
reporter.refresh_from_db()
F() 인스턴스를 QuerySet에 적용할 수 있다
reporter = Reporters.objects.filter(name='Tintin')
reporter.update(stories_filed=F('stories_filed') + 1)
Reporter.objects.all().update(stories_filed=F('stories_filed') + 1)
또한 F() 인스턴스를 orm query 메소드의 축약에 사용할 수도 있다
Entry.objects.filter(number_of_comments__gt=F('number_of_pingbacks'))