2012-03-06 26 views
7

Tôi có một mô hình với một số trường khóa ngoài, ví dụ: mô hình Sản phẩm với các loại 'loại', 'cấp', 'màu', 'cường độ' của các trường (chỉ là một ví dụ chung).Các biểu mẫu nội tuyến Django và các trường chọn tạo quá nhiều truy vấn db

Sau đó, tôi có một trang để chỉnh sửa tất cả các sản phẩm của một loại nhất định bằng cách sử dụng biểu mẫu Loại với sản phẩm làm biểu mẫu nội tuyến với tùy chọn thêm sản phẩm bổ sung nội tuyến sử dụng extra=10.

Điều tôi thấy rất lạ là mỗi lần khi tôi xuất một trong các trường lựa chọn khóa ngoài trên mẫu Django truy vấn cơ sở dữ liệu để nhận các tùy chọn (mọi lúc).

Ví dụ:

{% for form in formset %} 
    {{ form.level }} 
    {{ form.color }} 
    {{ form.intensity }} 
{% endfor %} 

Với 20 sản phẩm (và 10 hình thức thêm trống) các mã trên hành 30 select * from ... từ cấp, màu sắc và cường độ tổng cộng 90 câu truy vấn (tiết lộ bằng cách sử dụng Django debug toolbar), nơi 3 nên là đủ. Các tùy chọn không có khả năng thay đổi giữa yêu cầu, nhưng ngay cả khi họ đã làm tôi chắc chắn sẽ không muốn một số tùy chọn mới được thêm vào chỉ xuất hiện trong 5 hình thức mới nhất.

Có cách nào để tối ưu hóa mô hình/biểu mẫu/lượt xem/mẫu của tôi để cơ sở dữ liệu không bị búa như thế này một cách không cần thiết?

-

Disclaimer: Tôi là tương đối mới để django và python và không thể không nghĩ phải có một cách để giải quyết vấn đề này bằng cách nào đó được xây dựng trong.

Trả lời

4
field_queryset = Test.objects.all()  
for form in formset: 
     form.fields['test_field'].queryset = field_queryset 

Như thế này.

+0

Nice Denis, có ý nghĩa, chỉ cần làm cho tất cả chúng sử dụng cùng một đối tượng queryset. Đã cho bạn 11 tháng để kêu vang với một câu trả lời và tôi thêm 8 tháng để chấp nhận nó. Trong thời gian trung bình giải quyết vấn đề này bằng cách lưu trữ đầy đủ các kiểu 'loại', 'cấp', 'màu', trên tiền đề rằng đây là những hằng số khá nhiều sẽ không thay đổi. Nhưng cảm ơn, đây là một cách tiếp cận đơn giản mà tôi sẽ ghi nhớ trong lần sau. – davur

+0

Điều này không hoạt động. Các biểu mẫu sẽ được xây dựng với các queryset mặc định trước khi bạn có thể thay thế chúng như thế này, vì vậy nó sẽ thực hiện nhiều truy vấn. –

+1

@ Adrián, thực sự "có và không" tôi nghĩ vậy. Bạn nói đúng, các queryset mặc định có thể sẽ được tạo trong constructor của Form. Tuy nhiên, việc tạo một queryset không giống như truy vấn cơ sở dữ liệu. Nếu bạn thay thế queryset trước khi các truy vấn đầu tiên được phát hành, bạn vẫn có thể lưu tất cả các cuộc gọi không cần thiết vào cơ sở dữ liệu. Bạn sẽ cần phải thay thế chúng trước khi hiển thị biểu mẫu đầu tiên trong mẫu và trước khi gọi 'lưu' trên từng biểu mẫu. – davur

1

Bạn có thể change the queryset used by the formset, sau đó bạn có thể sử dụng select_related() để tạo các kết nối FK thay vì thực hiện truy vấn tại mỗi lần lặp forloop.

+1

Tôi không thấy những điều này sẽ giúp ích gì trong tình huống này. Bộ truy vấn là để chọn các giá trị hiện tại của sản phẩm và select_related có thể giúp tìm nạp các đối tượng mức/màu/cường độ hiện được liên kết với mỗi sản phẩm. Select_related thực sự giúp tìm nạp trước toàn bộ tập hợp các tùy chọn được chọn để điền vào hộp Chọn? – davur

+0

Ok để bạn có thể sử dụng tự động hoàn thành ajax (django-ajax-select) hoặc sử dụng bộ đệm truy vấn (johnnycache). – jpic

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