2011-12-19 27 views
23

làm cách nào tôi có thể có truy vấn phụ trong bộ truy vấn của django? ví dụ: nếu tôi có:cách truy vấn con trong queryset trong django?

select name, age from person, employee where person.id = employee.id and 
employee.id in (select id from employee where employee.company = 'Private') 

đây là những gì tôi đã làm.

Person.objects.value('name', 'age') 
Employee.objects.filter(company='Private') 

nhưng nó không làm việc vì nó sẽ trả về hai đầu ra ...

+2

Ví dụ của bạn không tốt lắm. Bạn không cần truy vấn con cho điều này: 'chọn tên, tuổi từ người, nhân viên nơi person.id = employee.id và employee.company = 'Private'' –

Trả lời

11
ids = Employee.objects.filter(company='Private').values_list('id', flat=True) 
Person.objects.filter(id__in=ids).values('name', 'age') 
+14

Đây không phải là truy vấn con,' values_list' không trả về queryset. Điều này tạo ra hai truy vấn riêng biệt. –

+1

Không phải truy vấn phụ, chỉ cần hai truy vấn. – Egg

+7

'values_list' trả về' ValuesQuerySet' và hai dòng đó sẽ thực sự chuyển thành một truy vấn đơn với truy vấn phụ. – BBT

31

như đã đề cập bởi trường hợp sử dụng ypercube của bạn không đòi hỏi subquery.

nhưng dù sao thì nhiều người truy cập trang này để tìm hiểu cách thực hiện truy vấn phụ ở đây là cách thực hiện.

employee_query = Employee.objects.filter(company='Private').only('id').all() 
Person.objects.value('name', 'age').filter(id__in=employee_query) 

Nguồn: http://mattrobenolt.com/the-django-orm-and-subqueries/

+0

Đề cập đến tài liệu: https://docs.djangoproject.com/en/1.9/ref/models/querysets/#in "cũng có thể sử dụng bộ truy vấn để đánh giá động danh sách giá trị thay vì cung cấp danh sách các giá trị theo nghĩa đen:" và "Queryset này sẽ được đánh giá là câu lệnh subselect". –

6

Bạn có thể tạo các truy vấn con trong Django bằng cách sử dụng một unevaluated queryset để lọc queryset chính của bạn. Trong trường hợp của bạn, nó sẽ giống như thế này:

employee_query = Employee.objects.filter(company='Private') 
people = Person.objects.filter(employee__in=employee_query) 

Tôi giả định rằng bạn có một mối quan hệ ngược Person-Employee tên employee. Tôi thấy hữu ích khi xem xét truy vấn SQL được tạo bởi một queryset khi tôi cố gắng hiểu cách các bộ lọc hoạt động.

print people.query 

Như những người khác đã nói, bạn không thực sự cần truy vấn phụ cho ví dụ của bạn. Bạn chỉ có thể tham gia vào bảng nhân viên:

people2 = Person.objects.filter(employee__company='Private') 
Các vấn đề liên quan