2010-08-17 22 views
33
myqueryset = Content.objects.filter(random 100) 

Trả lời

61
Content.objects.all().order_by('?')[:100] 

Xem order_by docs. Cũng lưu ý rằng cách tiếp cận này không quy mô tốt (trên thực tế, nó có quy mô thực sự, thực sự tồi tệ). Xem this SO answer để có cách tốt hơn để xử lý lựa chọn ngẫu nhiên khi bạn có một lượng lớn dữ liệu.

+5

Và tất cả() là dư thừa, nhưng tôi không bao giờ nhớ điều đó. – Tom

+0

Điều này thật tuyệt vời! Thông qua gỡ lỗi, tôi đã nhận thấy nó thậm chí tạo ra một truy vấn tốt, chỉ lấy 20 yếu tố, sử dụng 1 truy vấn, sử dụng ORDER BY RAND() cho ngẫu nhiên. Chúa ơi, thật tuyệt vời. –

9

Nếu bạn định thực hiện việc này nhiều lần, bạn cần thiết kế điều này vào cơ sở dữ liệu của mình.

Nếu bạn làm điều đó một lần, bạn có thể trả tiền phạt nặng. Điều này giúp bạn chính xác 100 với các thuộc tính ngẫu nhiên thực sự tốt. Tuy nhiên, nó sử dụng rất nhiều bộ nhớ.

pool= list(Content.objects.all()) 
random.shuffle(pool) 
object_list = pool[:100] 

Đây là một thuật toán khác cũng chậm vì nó có thể tìm kiếm toàn bộ bảng. Nó không sử dụng quá nhiều bộ nhớ và nó có thể không chính xác 100.

total_count= Content.objects.count() 
fraction = 100./total_count 
object_list = [ c for c in Content.objects.all() if random.random() < fraction ] 

Nếu bạn muốn làm điều này nhiều lần, bạn cần thêm thuộc tính vào nội dung để cho phép lọc hiệu quả "ngẫu nhiên "giá trị. Ví dụ, bạn có thể làm điều này.

class Content(models.Model): 
    ... etc. ... 
    def subset(self): 
     return self.id % 32768 

Điều này sẽ phân chia dữ liệu của bạn thành 32768 tập con riêng biệt. Mỗi tập hợp con là 1/32768'thông tin của bạn. Để nhận 100 mục ngẫu nhiên, bạn cần 100 * 32768/total_count tập hợp con dữ liệu của mình.

total_count = Content.objects.count() 
no_of_subsets= 100*32768/total_count 
object_list = Content.objects.filter(subset__lte=no_of_subsets) 

Đây là nhanh và đó là tái sản xuất. Các tập con là "tùy ý" không về mặt kỹ thuật "ngẫu nhiên".

+0

Điểm tốt cho hiệu suất –

+0

Tôi thích cách tiếp cận cuối cùng của bạn mặc dù tôi không nghĩ rằng bạn có thể lọc trên các thuộc tính. Bạn sẽ phải thêm cột tập hợp con vào chính mô hình và đặt giá trị của nó khi lưu như sau: http://ifacethoughts.net/2009/07/14/calculated-fields-in-django/ – jesal

+0

Thêm tập hợp con làm phương thức đối với mô hình Nội dung không đủ để lọc, như được đề xuất trong đoạn trích cuối cùng của bạn. –

1

tôi làm:

import random  
object_list = list(Content.objects.filter(foo=bar).values()[:100]) 
random.shuffle(object_list) 

Chạy chỉ truy vấn MySQL đơn đơn giản và tốt về hiệu suất.

+1

Điều này không trả về các bản ghi ngẫu nhiên từ cơ sở dữ liệu. Nó chọn kỷ lục trăm đầu tiên và xáo trộn chúng. Hồ sơ 101 trở đi không có cơ hội được chọn. – Blair

+0

Tôi muốn đề xuất cách sử dụng hàm trộn trên order_by ('?') Có các vấn đề nghiêm trọng về hiệu suất: http://stackoverflow.com/a/6405601/232649 Để xáo trộn tất cả các bản ghi: shuffle (danh sách (Content.objects) .all())) [: 100] – Pratyush

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