2011-07-01 59 views
5

Nói rằng tôi có một mô hình:django-taggit: Có cách nào để tạo ra các truy vấn db ít hơn không?

class Entry(models.Model): 
    ... 
    tags = TaggableManager() 

Khi tôi lặp trên Entry.objects.all() trong một mẫu, entry.tags.all tạo một truy vấn nhiều cơ sở dữ liệu. Có thể giảm số lượng truy vấn không? Sử dụng một cái gì đó như select_related() (Tôi biết nó sẽ không làm việc, kể từ khi django-taggit sử dụng mối quan hệ manytomany, nhưng tôi chắc chắn nên có một cách để chọn tất cả các mục với các thẻ liên quan trong 1 hit)?

+0

thể trùng lặp của [Django-taggit prefetch \ _related] (http://stackoverflow.com/questions/12926036/django-taggit-prefetch-related), hoặc có thể http://stackoverflow.com/câu hỏi/12204511/tối ưu hóa-django-truy vấn-to-pull-nước ngoài-key-và-django-taggit-mối quan hệ –

Trả lời

0

Hãy thử sử dụng Select Reverse thiết kế để lấy toàn bộ mối quan hệ nhiều2many với một truy vấn.

2

Từ Django 1.4 trở đi, bạn có thể sử dụng prefetch_related để truy xuất quan hệ một-nhiều trên một truy vấn trong một truy vấn. Thật không may điều này không làm việc rực rỡ với django-taggit, bởi vì các 'thẻ' tài sản là một người quản lý chứ không phải là một mối quan hệ thực sự, và vì vậy prefetch_related không thể làm cho tinh thần của nó. Thay vào đó, bạn cần phải làm theo các mối quan hệ tagged_items:

entries = Entry.objects.prefetch_related('tagged_items__tag')

Sau đó bạn cần phải đi qua một số vặn vẹo tương tự trong mẫu mã để truy cập vào các thẻ nạp trước, bởi vì entry.tags.all sẽ chạy truy vấn khác chứ không phải là làm cho việc sử dụng prefetch:

{% for tagged_item in entry.tagged_items %} 
    <li>{{ tagged_item.tag.name }}</li> 
{% endfor %} 
+2

Chỉ cần một lưu ý - điều này gây ra lỗi GenericRelatedObjectManager cho tôi. Tôi đã thay đổi 'entry.tagged_items' thành' entry.tagged_items.all' và nó hoạt động, nhưng không phải với bất kỳ cải tiến nào trong các truy vấn SQL trên mã ban đầu. Bối rối ở đây. – Laurence

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