데이터베이스에서 레코드를 조회할 때는 Model클래스를 관리하는 Manager클래스를 이용한다. 가장 간단하게는 모든 레코드를 가져오는 방법이 있는데, 모델마다 기본적으로 제공되는 object라는 매니저를 이용한다. object 매니저로 레코드를 조회하면 QuerySet이 반환된다. 이는 관계형 데이터베이스 CLI인 JDBC의 ResultSet과 유사하다. = filter = 한 모델에 대해서는 여러 가지 필터를 설치할 수 있다. 필터는 SQL문에서 where절에 해당하는 역할을 한다. 필터에는 검색하는 컬럼의 완전 일치, 부분 일치, 사이 값, 포함, 연월일 옵션을 줄 수 있다. 기본적으로 필터는 AND 조합으로 이루어지며, OR조합을 사용하고 싶다면 Q라는 쿼리 오브젝트를 사용해야 한다.[9] 아래는 필터를 이용해 보고 날짜가2006년 10월 1일 이후인 위험 보고서를 찾는 python코드와 그에 해당하는 SQL문을 보여준다. {{{ RiskReport.objects.filter(date__gt=datetime.date(2006, 10, 1)) }}} {{{ SELECT ... FROM risk_report WHERE date > '2006-10-1' }}} = select_related = 일대다 관계인 레코드의 경우는 selete_related메소드를 이용하면 데이터베이스 접근 횟수를 줄일 수 있다. 일반적인 데이터베이스 조회는 추상화되어있어 실행할 때마다 쿼리를 수행한다. 하지만 selete_related메소드를 사용하면 한 번 데이터베이스에서 결과를 가져온 후 필요할 때는 이를 그대로 사용한다. 다음 예제에서 두 방식이 어떻게 다른지 확인할 수 있다. {{{ # 데이터베이스에서 한 번 값을 가져온다. c = ControlReport.objects.get(id=1) # Employee테이블에 접근하기 위해 다시 데이터베이스에서 값을 가져온다. r = c.reporter }}} {{{ # 데이터베이스에서 값을 미리 가져온다. c = ControlReport.objects.select_related().get(id=1) # 이전에 Employee값까지 가져왔기 때문에 다시 데이터베이스에서 값을 가져오지 않는다. r = c.reporter }}} = extra = 사용자는 원하는 경우 extra메서드를 이용해 원하는 컬럼을 추가한 결과를 얻을 수 있다. 다음은 2006년 1월 1일 이후 보고서를 최신으로 표시하는 컬럼을 가진 리포트 정보를 가져온다. {{{ RiskReport.objects.extra(select={'is_recent': " date > '2006-01-01'"}) }}} 이는 다음 SQL과 같다. {{{ SELECT blog_entry.*, (pub_date > '2006-01-01') FROM blog_entry; }}} extra메소드를 사용하면 다음과 같은 조금 복잡한 질의도 할 수 있다. 각 직원이 몇 번이나 위험 보고서를 작성했는지 알아낸다. {{{ Employee.objects.extra( select={ 'num_of_report': 'SELECT COUNT(*) FROM risk_report WHERE risk_report.reporter = employee.id' }, ) }}} {{{ SELECT employee.*, (SELECT COUNT(*) FROM risk_report WHERE risk_report.reporter = employee.id) FROM employee; }}} where절을 사용하는 것 역시 가능하다.[7] 하지만 중첩질의는 지원하지 않는다. {{{ RiskReport.objects.extra(where=['id IN (3, 4, 5, 20)']) }}} {{{ SELECT * FROM risk_report WHERE id IN (3, 4, 5, 20); }}} = values = 사용자는 values함수를 이용해서 원하는 속성을 지정할 수 있다. 이는 검색 조건을 만족하는 레코드의 필요한 속성만을 이용하므로 효율적이다. 또한 values함수는 QuerySet을 상속한 ValuesQuerySet을 리턴하므로 다시 위에서 사용한 검색 조건을 사용할 수 있다. 하지만 ValuesQuerySet은 사전형(dictionary) 자료구조를 가지고 있기 때문에, 많은 수의 레코드를 얻어오기에는 부적절하다. 다음은 사원 정보에서 이메일 속성만을 얻어온다. {{{ Employee.objects.values('email') }}} = join = Django에서 기본적으로 제공하는 조인 연산은 없다. SQL문을 직접 수행하여 원하는 결과를 얻을 수 있다. 이는 JDBC의 인터페이스와 비슷하며, 커서를 이용하여 질의를 수행한 결과를 하나씩 얻어오는 방식을 사용한다. 다음은 특정 부서 에서 시행한 위험 관리 대책을 얻어오는 함수이다. {{{ def getDartmentControl(depart_id): from django.db import connection cursor = connection.cursor() qeury=' ' ' select report_controlreport.content from report_controlreport, report_department_employees where report_department_employees.department_id = report_department_employees.employee_id and report_department_employees.employee_id = report_controlreport.reporter_id and report_department_employees.department_id= %d' ' ' cursor.execute(query, [depart_id]) row = cursor.fetchone() return row }}} ---- [django/Example]