2009-04-28 37 views
10

tôi có các mô hình sau:Làm thế nào để hạn chế lựa chọn lĩnh vực lựa chọn dựa trên một lĩnh vực lựa chọn trong django quản trị

class Category(models.Model): 
    name = models.CharField(max_length=40) 

class Item(models.Model): 
    name = models.CharField(max_length=40) 
    category = models.ForeignKey(Category) 

class Demo(models.Model): 
    name = models.CharField(max_length=40) 
    category = models.ForeignKey(Category) 
    item = models.ForeignKey(Item) 

Trong giao diện quản trị khi tạo một Demo mới, sau khi người dùng chọn mục từ menu thả xuống, tôi sẽ muốn giới hạn số lượng lựa chọn trong menu thả xuống "mục". Nếu người dùng chọn một danh mục khác thì lựa chọn mục sẽ cập nhật tương ứng. Tôi muốn giới hạn các lựa chọn mục ngay trên máy khách, trước khi nó thậm chí chạm vào việc xác thực biểu mẫu trên máy chủ. Điều này là dành cho khả năng sử dụng, bởi vì danh sách các mục có thể là 1000+ có thể thu hẹp nó theo thể loại sẽ giúp làm cho nó dễ quản lý hơn.

Có cách nào "django-way" làm việc đó hay JavaScript tùy chỉnh là tùy chọn duy nhất ở đây?

+1

Thực sự không có cách nào để thiết lập điều này trong các mô hình Django? –

+0

Vâng. Với ứng dụng của bên thứ ba. Xem câu trả lời của tôi. –

Trả lời

10

Dưới đây là một số javascript (JQuery dựa) để thay đổi các giá trị tùy chọn mục khi loại thay đổi:

<script charset="utf-8" type="text/javascript"> 
    $(function(){ 
    $("select#id_category").change(function(){ 
     $.getJSON("/items/",{id: $(this).val(), view: 'json'}, function(j) { 
     var options = '<option value="">--------&nbsp;</option>'; 
     for (var i = 0; i < j.length; i++) { 
      options += '<option value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</option>'; 
     } 
     $("#id_item").html(options); 
     $("#id_item option:first").attr('selected', 'selected'); 
     }) 
     $("#id_category").attr('selected', 'selected'); 
    }) 
    }) 
</script> 

Bạn cần một cái nhìn được gọi là trên/mặt hàng/URL mà cung cấp một danh sách JSON của hợp lệ mặt hàng.

Bạn có thể móc điều này vào quản trị viên của mình bằng cách sử dụng model admin media definitions.

+0

+1 -> Tôi sắp đăng một thứ rất giống. OP chỉ cần điền danh sách bằng cách sử dụng thông tin trong db và sau đó chuyển các tùy chọn bằng cách sử dụng JS mà bạn đã cung cấp :-) –

+0

... hoặc nếu bạn không muốn tải tất cả cùng một lúc, bạn có thể sử dụng một số ajax để yêu cầu danh mục từ máy chủ mỗi khi người dùng thay đổi tùy chọn. Phụ thuộc vào việc bạn muốn thực hiện cú đánh trước hay trì hoãn họ khi họ chọn ... –

+0

Cảm ơn Jon. Nếu bạn muốn, bạn nên đi trước một bài viết mã của bạn mà populates danh sách tại thời gian tải thay vì ajax như tôi. Sau đó, OP có thể chọn thích hợp hơn. –

0

Suy nghĩ JavaScript/AJAX sẽ là phương pháp tốt nhất cho vấn đề này.

+3

Dường như một nhận xét về câu trả lời ở trên hơn là câu trả lời của chính nó. – boatcoder

0

Bạn sẽ cần phải có một số loại cơ chế dựa trên máy chủ không lọc các đối tượng. Hoặc là, hoặc bạn có thể tải lại trang khi lựa chọn được thực hiện (có khả năng được thực hiện trong JavaScript anyway).

Nếu không, không có cách nào để lấy tập con dữ liệu từ máy chủ cho máy khách.

4

django-smart-selects:

Nếu bạn có mô hình sau:

class Location(models.Model) 
    continent = models.ForeignKey(Continent) 
    country = models.ForeignKey(Country) 
    area = models.ForeignKey(Area) 
    city = models.CharField(max_length=50) 
    street = models.CharField(max_length=100) 

Và bạn muốn rằng nếu bạn chọn một lục địa chỉ các nước có sẵn mà nằm trên lục địa này và tương tự cho các khu vực bạn có thể làm như sau:

from smart_selects.db_fields import ChainedForeignKey 

class Location(models.Model) 
    continent = models.ForeignKey(Continent) 
    country = ChainedForeignKey(
     Country, 
     chained_field="continent", 
     chained_model_field="continent", 
     show_all=False, 
     auto_choose=True 
    ) 
    area = ChainedForeignKey(Area, chained_field="country", chained_model_field="country") 
    city = models.CharField(max_length=50) 
    street = models.CharField(max_length=100) 
Các vấn đề liên quan