2013-10-31 16 views
32

Những hai đoạn mã giống hệt nhau tại blush đầu tiên:Sử dụng phương thức get_queryset() hoặc đặt biến truy vấn?

class IndexView(generic.ListView): 
    template_name = 'polls/index.html' 
    context_object_name = 'latest_poll_list' 
    queryset = Poll.active.order_by('-pub_date')[:5] 

class IndexView(generic.ListView): 
    template_name = 'polls/index.html' 
    context_object_name = 'latest_poll_list' 

    def get_queryset(self): 
     return Poll.active.order_by('-pub_date')[:5] 

Có sự khác biệt giữa chúng? Và nếu đó là:

Cách tiếp cận nào tốt hơn? Hoặc khi đặt biến số queryset tốt hơn là ghi đè phương thức get_queryset? Và ngược lại.

Trả lời

47

Trong ví dụ của bạn, trọng querysetget_queryset có tác dụng tương tự. Tôi sẽ ưu tiên thiết lập queryset vì nó ít tiết hơn.

Khi bạn đặt queryset, bộ truy vấn chỉ được tạo một lần, khi bạn khởi động máy chủ của mình. Mặt khác, phương thức get_queryset được gọi cho mọi yêu cầu.

Điều đó có nghĩa là get_queryset hữu ích nếu bạn muốn điều chỉnh truy vấn động. Ví dụ, bạn có thể trở lại đối tượng mà thuộc về người sử dụng hiện tại:

class IndexView(generic.ListView): 
    def get_queryset(self): 
     """Returns Polls that belong to the current user""" 
     return Poll.active.filter(user=self.request.user).order_by('-pub_date')[:5] 

Một ví dụ khác nơi get_queryset rất hữu ích là khi bạn muốn lọc dựa trên một callable, ví dụ, trở lại các cuộc thăm dò hôm nay:

class IndexView(generic.ListView): 
    def get_queryset(self): 
     """Returns Polls that were created today""" 
     return Poll.active.filter(pub_date=date.today()) 

Nếu bạn cố gắng làm điều tương tự bằng cách đặt queryset thì date.today() sẽ chỉ được gọi một lần, khi chế độ xem được tải và chế độ xem sẽ hiển thị kết quả không chính xác sau một thời gian.

class IndexView(generic.ListView): 
    # don't do this! 
    queryset = Poll.active.filter(pub_date=date.today()) 
+2

bạn cũng có thể viết trong 'get_queryset'' self.model.objects.filter (...) '. Trong trường hợp kế thừa danh sách riêng, bạn nên nhớ rằng người ta nên tham khảo 'siêu (YourListViewExtendingSomeOtherLV, self) .get_queryset(). Filter (...)' – andi

4

Thuộc tính queryset được sử dụng trong nội bộ, luôn luôn sử dụng phương pháp này (bạn sẽ thường xuyên phải thực hiện truy vấn tùy chỉnh dựa trên yêu cầu hoặc phiên vars ví dụ)

8

câu trả lời khác đã bỏ lỡ một ý nghĩa quan trọng của sự kiện là thuộc tính queryset được đánh giá khi quá trình khởi động. Vì bạn không chỉ tạo truy vấn, bạn thực sự đang cắt, truy vấn sẽ là được đánh giá tại thời điểm đó. Điều đó có nghĩa là bạn sẽ chỉ nhận được 5 cuộc thăm dò hàng đầu tại thời điểm đó và chúng sẽ không làm mới ngay cả khi bạn tạo một cuộc thăm dò khác cho đến khi quá trình được khởi động lại.

Đây chính là thời điểm bạn nên sử dụng get_queryset().

+0

Theo [docs] (https: //docs.djangoproject .com/vi/1.8/ref/models/querysets/# khi-querysets-được-đánh giá), việc cắt một queryset chưa được đánh giá sẽ không làm cho nó được đánh giá trừ khi bạn sử dụng tham số 'step' của cú pháp slice. – Alasdair

1

Mô hình và bộ truy vấn rất giống nhau, nhưng giá trị của bộ truy vấn nếu cung cấp ghi đè của mô hình.

Mô hình là loại đối tượng mà chế độ xem này hiển thị.

Overriding get_queryset kiểm soát những gì trường hợp cụ thể này xem màn (ví dụ: 5 trường hợp cuối cùng được tạo ra)

Từ tài liệu của Django: mô hình

:

mô hình

Các rằng quan điểm này sẽ hiển thị dữ liệu cho. Chỉ định mô hình = Foo có hiệu quả giống như chỉ định queryset = Foo.objects.all(), trong đó đối tượng là viết tắt của trình quản lý mặc định của Foo.

queryset:

Một QuerySet đại diện cho các đối tượng. Nếu được cung cấp, giá trị của queryset thay thế giá trị được cung cấp cho mô hình.

get_queryset:

get_queryset() Trả về queryset sẽ được sử dụng để lấy các đối tượng rằng quan điểm này sẽ hiển thị. Theo mặc định, get_queryset() trả về giá trị của thuộc tính queryset nếu nó được thiết lập, nếu không nó sẽ tạo một QuerySet bằng cách gọi phương thức all() trên trình quản lý mặc định của thuộc tính mô hình.

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