2013-08-14 26 views
6

Tôi muốn nối thêm hoặc chuỗi một số Querysets trong Django, giữ nguyên thứ tự của mỗi một (không phải kết quả). Tôi đang sử dụng thư viện của bên thứ ba để phân trang kết quả và chỉ chấp nhận danh sách hoặc queryset. Tôi đã thử các tùy chọn này:Làm thế nào để chuỗi các truy vấn Django bảo quản thứ tự riêng lẻ

Truy vấn tham gia: Không bảo toàn trật tự trong các truy vấn riêng lẻ, vì vậy tôi không thể sử dụng điều này.

result = queryset_1 | queryset_2 

Sử dụng itertools: Gọi list() trên đối tượng chuỗi thực sự đánh giá queryset và điều này có thể gây ra rất nhiều chi phí. Phải không?

result = list(itertools.chain(queryset_1, queryset_2)) 

Bạn nghĩ tôi nên đi như thế nào?

Trả lời

4

Nếu queryset là các mô hình khác nhau, bạn cần phải đánh giá chúng vào danh sách và sau đó bạn chỉ có thể thêm:

result = list(queryset_1) + list(queryset_2) 

Nếu họ là những mô hình tương tự, bạn nên kết hợp các truy vấn bằng cách sử dụng Q object và ' order_by ("trường queryset_1", "trường queryset_2") '.

Câu trả lời đúng chủ yếu phụ thuộc vào lý do bạn muốn kết hợp những điều này và cách bạn sẽ sử dụng kết quả.

+0

tôi đang làm một Kết phức tạp trên cùng một mô hình tách ra ở một số truy vấn. Mỗi một truy xuất hồ sơ phù hợp với một điều kiện nhất định và mỗi một được sắp xếp theo một cách cụ thể. Kết quả phải bao gồm các kết quả từ mỗi queryset và phải duy trì thứ tự của mỗi queryset này. Vì vậy, tôi không thể sử dụng các đối tượng 'Q' ở đây, vì tôi sẽ không được phép thực hiện một số' order_by() 'trên cùng một truy vấn. Tôi muốn tránh gọi 'list()' trên mỗi queryset để tránh truy cập cơ sở dữ liệu, lấy quá nhiều đối tượng trong bộ nhớ. – Caumons

+0

Bạn có nghĩ rằng có thể tạo một truy vấn SQL thuần túy để trả về một tập hợp các hàng được sắp xếp và lọc chính xác như bạn muốn không? Nếu không, thì một QuerySet đơn lẻ cũng không thể thực hiện được.Ví dụ: nếu bạn đặt hai tập hợp kết quả theo các cách không tương thích. Nếu bạn làm việc xung quanh sự không tương thích này bằng cách sử dụng một phép nối phức tạp từ hai bộ kết quả được sắp xếp rõ ràng, đó không phải là thứ mà django ORM có thể làm. – Demiurge

+0

Tôi không muốn nhận được vào SQL tinh khiết nhiều như tôi có thể ở lại với ORM của Django. Tôi đã chỉ yêu cầu điều này để xem nếu có một lựa chọn tốt hơn cho những gì tôi đang làm (hiện đang sử dụng ví dụ thứ hai) với một truy vấn hạn chế để tránh có hàng ngàn đối tượng trong bộ nhớ. – Caumons

0

Nếu bạn cần hợp nhất hai queryset vào một truy vấn thứ ba, đây là ví dụ, sử dụng _result_cache.

mô hình

class ImportMinAttend(models.Model): 
    country=models.CharField(max_length=2, blank=False, null=False) 
    status=models.CharField(max_length=5, blank=True, null=True, default=None) 

Từ mô hình này, tôi muốn hiển thị một danh sách tất cả các hàng như vậy:

  1. (truy vấn 1) Tình trạng trống đi đầu tiên, sắp xếp theo các nước
  2. (truy vấn 2) trạng thái không trống đi theo thứ hai, được sắp xếp theo quốc gia

Tôi muốn kết hợp truy vấn 1 và truy vấn 2.

#get all the objects 
    queryset=ImportMinAttend.objects.all() 

    #get the first queryset 
    queryset_1=queryset.filter(status=None).order_by("country") 
    #len or anything that hits the database 
    len(queryset_1) 

    #get the second queryset 
    queryset_2=queryset.exclude(status=None).order_by("country") 

    #append the second queryset to the first one AND PRESERVE ORDER 
    for query in queryset_2: 
     queryset_1._result_cache.append(query) 

    #final result 
    queryset=queryset_1 

Nó có thể không hiệu quả lắm, nhưng nó hoạt động :).

+0

Điều này có vẻ hiệu quả hơn nhiều so với danh sách gọi() trên cả hai queryset. Nếu bạn lặp lại trên nhỏ nhất này có vẻ tốt hơn. Những gì tôi không thích là sửa đổi thuộc tính riêng _result_cache ... Bạn có chắc chắn điều này là an toàn không? – Caumons

+0

Cách tiếp cận này sẽ vẫn đánh giá tất cả các queryset giống như việc tạo danh sách các truy vấn đó là tác giả của câu hỏi không muốn. –

Các vấn đề liên quan