2009-11-27 31 views
26

Tôi đang tìm cách thu hẹp truy vấn được đặt cho một trường biểu mẫu có một khóa ngoại tuyến vào bảng Người dùng xuống nhóm mà người dùng thuộc về.Django: Cách lọc Người dùng thuộc về một nhóm cụ thể

Các nhóm trước đây đã được tôi liên kết. Mô hình này có thể có một cái gì đó như sau:

myuser = models.ForeignKey(User) 

Và ModelForm của tôi là xương rất trần:

class MyForm(ModelForm): 
    class Meta: 
     model = MyModel 

Vì vậy, khi tôi nhanh chóng hình thức tôi làm điều gì đó như thế này trong views.py tôi:

form = MyForm() 

Bây giờ câu hỏi của tôi là, làm cách nào tôi có thể lấy trường myuser và lọc để chỉ người dùng nhóm 'foo' hiển thị .. giống như:

form.fields["myuser"].queryset = ??? 

Các truy vấn trong SQL trông như thế này:

mysql> SELECT * from auth_user INNER JOIN auth_user_groups ON auth_user.id = auth_user_groups.user_id INNER JOIN auth_group ON auth_group.id = auth_user_groups.group_id WHERE auth_group.name = 'client'; 

Tôi muốn tránh sử dụng SQL thô mặc dù. nó có khả thi để làm vậy không?

Trả lời

42

Bạn sẽ muốn sử dụng Django's convention for joining across relationships để tham gia vào bảng nhóm trong bộ truy vấn của mình.

Trước tiên, tôi khuyên bạn nên cung cấp mối quan hệ của mình related_name. Điều này làm cho mã dễ đọc hơn những gì Django tạo theo mặc định.

class Group(models.Model): 
    myuser = models.ForeignKey(User, related_name='groups') 

Nếu bạn muốn chỉ một nhóm duy nhất, bạn có thể tham gia trên mối quan hệ đó và so sánh các trường tên sử dụng một trong các phương pháp:

form.fields['myuser'].queryset = User.objects.filter(
    groups__name='foo') 
form.fields['myuser'].queryset = User.objects.filter(
    groups__name__in=['foo']) 

Nếu bạn muốn để đủ điều kiện nhiều nhóm, sử dụng in khoản:

form.fields['myuser'].queryset = User.objects.filter(
    groups__name__in=['foo', 'bar']) 

Nếu bạn muốn nhanh chóng nhìn thấy SQL được tạo ra, bạn có thể làm điều này:

qs = User.objects.filter(groups__name='foo') 
print qs.query 
+0

Tuyệt vời, cảm ơn Joe. Tôi đã đăng câu lệnh SQL này ở trên bên phải khi bạn đăng câu trả lời. Đánh giá cao phản hồi, hoạt động tuyệt vời. – randombits

+1

Không có prob, tôi đã quay lại và chỉnh sửa nó để chỉ cho bạn cách in ra SQL cho một bộ truy vấn để bạn có thể so sánh nó với những gì bạn đang mong đợi. –

13

Đây là một câu hỏi thực sự cũ, nhưng đối với những người googling câu trả lời cho điều này (như tôi đã làm), xin vui lòng biết rằng câu trả lời chấp nhận không còn chính xác 100%. Người dùng có thể thuộc về nhiều nhóm, vì vậy để kiểm tra một cách chính xác nếu người dùng là ở một số nhóm, bạn nên làm:

qs = User.objects.filter(groups__name__in=['foo']) 

Tất nhiên, nếu bạn muốn kiểm tra cho nhiều nhóm, bạn có thể thêm những vào danh sách :

qs = User.objects.filter(groups__name__in=['foo', 'bar']) 
+4

Tôi đã cập nhật câu trả lời của mình để phản ánh mối quan tâm của bạn về việc đủ điều kiện cho nhiều nhóm, nhưng không có gì sai khi sử dụng '=' thay vì 'in' nếu bạn đang cố gắng giới hạn một nhóm. –

+1

Thứ hai @JoeHolloway tại đây. Định dạng 'User.objects.filter (groups__name = 'foo')' hoạt động hoàn toàn tốt khi truy vấn người dùng trong một nhóm. – CoreDumpError

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