2012-03-15 25 views
34

tôi muốn biết là có bất cứ điều gì tương đương với:Django: Tương đương của "chọn [tên cột] từ [tablename]"

select columnname from tablename 

Giống như Django hướng dẫn nói:

Entry.objects.filter(condition) 

lấy về tất cả các đối tượng với điều kiện đã cho. Nó giống như:

select * from Entry where condition 

Nhưng tôi muốn tạo một danh sách chỉ có một cột [trường hợp của tôi là khóa ngoại]. Tìm thấy rằng:

Entry.objects.values_list('column_name', flat=True).filter(condition) 

cũng làm như vậy. Nhưng trong trường hợp của tôi, cột là khóa ngoại, và truy vấn này mất đi thuộc tính của khóa ngoài. Nó chỉ lưu trữ các giá trị. Tôi không thể thực hiện các cuộc gọi tra cứu.

+1

Tôi bắt đầu viết câu trả lời và giờ tôi không chắc chắn. Bạn có muốn django trả lại một đối tượng từ khóa ngoài hay bạn có muốn chính khóa đó không? –

Trả lời

51

Tất nhiên, valuesvalue_list sẽ truy lục giá trị thô từ cơ sở dữ liệu. Django không thể làm việc "ma thuật" của nó trên một mô hình có nghĩa là bạn không nhận được để đi qua các mối quan hệ bởi vì bạn đang mắc kẹt với id khóa ngoại đang hướng tới, chứ không phải là trường ForeignKey.

Nếu bạn cần phải lọc những giá trị đó, bạn có thể làm như sau (giả sử column_name là một ForeignKey trỏ đến MyModel):

ids = Entry.objects.values_list('column_name', flat=True).filter(...) 
my_models = MyModel.objects.filter(pk__in=set(ids)) 

Dưới đây là một tài liệu cho values_list()

+1

điều này có thể hoạt động nhưng nếu đó là tôi Tôi không hài lòng về việc phải thực hiện hai cuộc gọi đến cơ sở dữ liệu. @Gareth Rees có một cách tiếp cận tốt hơn - lật các truy vấn xung quanh và viết nó từ quan điểm của đối tượng bạn muốn và tận dụng lợi thế của related_name – ThatAintWorking

5

Để hạn chế truy vấn thiết lập để một cột cụ thể (s) bạn sử dụng .values ​​(columname)

Bạn cũng nên có lẽ thêm rõ rệt đến cùng, vì vậy truy vấn của bạn sẽ kết thúc hạnh phúc:

Entry.objects.filter(myfilter).values(columname).distinct() 

Xem: https://docs.djangoproject.com/en/dev/ref/models/querysets/#django.db.models.query.QuerySet.values

để biết thêm thông tin

Tùy thuộc vào câu trả lời của bạn trong các bình luận, tôi sẽ trở lại và chỉnh sửa.

Chỉnh sửa:

Tôi không chắc chắn liệu phương pháp này có đúng hay không. Bạn có thể nhận được tất cả các đối tượng của bạn trong một danh sách python bằng cách nhận một queryset bình thường thông qua bộ lọc và sau đó thực hiện:

myobjectlist = map(lambda x: x.mycolumnname, myqueryset) 

Vấn đề duy nhất với cách tiếp cận đó là nếu queryset của bạn là lớn sử dụng bộ nhớ của bạn sẽ được bình đẳng lớn .

Dù sao, tôi vẫn không chắc chắn về một số chi tiết cụ thể của sự cố.

+2

giá trị() cho kết quả tương tự với values_list(). Tôi nhận được các giá trị cột 'người dùng' là 1L, 2L ... nhưng mối quan hệ khóa ngoại bị mất. Tôi không thể truy cập lớp 'người dùng'. – Anuj

+0

Bạn cần 'order_by' để' phân biệt' để thực hiện công việc của nó. –

+0

một giải pháp tương tự, không thanh lịch để nhận các mặt hàng thay vì ID là: [instance.member chẳng hạn trong Entry.filter (điều kiện) .distinct ('member')] – Nimo

9

Bạn có một mô hình A với khóa ngoài cho mô hình khác B và bạn muốn chọn số B được giới thiệu bởi một số A. Có đúng không?Nếu vậy, các truy vấn mà bạn muốn chỉ là:

B.objects.filter(a__isnull = False) 

Nếu bạn có điều kiện về A tương ứng, sau đó truy vấn có thể là:

B.objects.filter(a__field1 = value1, a__field2 = value2, ...) 

Xem Django's backwards relation documentation cho một lời giải thích lý do tại sao các công trình này, và ForeignKey.related_name option nếu bạn muốn thay đổi tên của mối quan hệ ngược.

+0

Tôi nghĩ rằng đây là cách tiếp cận tốt hơn nhưng bạn có lẽ nên đề cập đến sử dụng related_name – ThatAintWorking

+2

@Ron: Tôi đã thêm liên kết vào tài liệu. –

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