2009-08-04 23 views
16

Tôi muốn tìm một chuỗi nhất định trong một số trường của Mô hình ở Django. Lý tưởng nhất, nó sẽ giống như sau:Cách tự động cung cấp tên trường tra cứu trong truy vấn Django?

keyword = 'keyword' 
fields = ['foo', 'bar', 'baz'] 
results = [] 
for field in fields: 
    lookup = "%s__contains" 
    results.append(Item.objects.filter(lookup=keyword)) 

Tất nhiên điều này sẽ không hoạt động, vì "tra cứu" không thể được giải quyết vào một trường. Có cách nào khác để làm điều này?

+0

Cảm ơn bạn đã liên kết song công - Tôi đang tìm kiếm nhưng thật khó để kết hợp đúng từ khóa trong từ khóa này. –

Trả lời

15

Tôi nghĩ có thể có cách tốt hơn để thực hiện việc này với hệ thống truy vấn Django. Đây là cách làm theo cách của bạn.

Python cho phép bạn chuyển các từ điển được sử dụng làm danh sách đối số bằng cách thêm tiền tố cho chúng bằng **. Với một điểm may mắn, bạn sẽ có thể làm điều gì đó như thế này:

lookup = "%s__contains" % field 
results.append(Item.objects.filter(**{ lookup: keyword})) 
+0

Hãy xem câu trả lời của Botondus dưới đây. Đó là giải pháp với hệ thống truy vấn Django mà tôi đã đề cập đến, và hy vọng nó sẽ chạy nhanh hơn vì nó sẽ thực thi trong SQL. –

4

Tôi thích câu trả lời DialZ nhưng vì lý do hiệu suất mà bạn nên xây dựng các truy vấn và sau đó nhấn cơ sở dữ liệu một lần thay vì concatenating tất cả các kết quả vào một danh sách:

keyword = 'keyword' 
fields = ['foo', 'bar', 'baz'] 

# this makes an empty queryset object which we can 
# add to later using the | operator 
results = Item.objects.none() 

for field in fields: 
    lookup = "%s__contains" % field 
    query = {lookup : keyword} 
    results = results | Item.objects.filter(**query) 

Tôi không thực hiện một trong những điều này trong một thời gian, nhưng tôi chắc chắn django sẽ không thực sự đánh vào cơ sở dữ liệu ở tất cả trong mã này. Nó sẽ chỉ thực hiện truy vấn khi bạn truy cập dữ liệu chứa trong các bản ghi

23

Tôi muốn sử dụng đối tượng Q cho một thứ như thế này.

from django.db.models import Q 

keyword = 'keyword' 
fields = ['foo', 'bar', 'baz'] 

Qr = None 
for field in fields: 
    q = Q(**{"%s__contains" % field: keyword }) 
    if Qr: 
     Qr = Qr | q # or & for filtering 
    else: 
     Qr = q 

# this you can now combine with other filters, exclude etc.  
results = MyModel.objects.filter(Qr) 
+1

Đây là một câu trả lời hoàn toàn tuyệt vời. Nó làm cho ngày của tôi để đi qua nó. Bạn đã đăng về điều này ở bất cứ đâu? Tôi không nghĩ rằng hầu hết mọi người nhận ra rằng điều này là có thể (looping trên tên trường để cư một dict của Q kwargs đối tượng). – jMyles

+1

@jMyles: Cảm ơn, vui vì tôi có thể giúp. Không, tôi không nghĩ rằng tôi đã đăng về nó ở nơi khác. Nhưng nói chung kết hợp các đối tượng 'Q' một cách năng động, là một phương pháp rất mạnh mẽ để xây dựng các truy vấn phức tạp một cách dễ dàng. –

+0

Tôi vừa đăng câu hỏi mà câu trả lời có thể tương tự - tôi có thể sử dụng vòng lặp và toán tử Q và toán tử. Nó ở đây: http://stackoverflow.com/questions/6783747/django-queryset-to-match-all-related-objects – jMyles

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