2011-10-06 4 views
8

Tôi có một số sở thích được sắp xếp thành các danh mục. Đối với mỗi thể loại, tôi muốn có thể chọn một người chiến thắng foo.Django - Giới hạn lựa chọn đối với nội dung phụ thuộc vào cá thể

Do đó tôi có các mô hình trông như thế này:

class Category(models.Model): 
    name = models.CharField(max_length=30) 
    # More fields... 
    winner = models.ManyToManyField(
     'Foo', 
     related_name='winner' 
    ) 

class Foo(models.Model): 
    name = models.CharField(max_length=30) 
    # More fields... 
    category = models.ForeignKey(
     Category, 
     related_name='category' 
    ) 

(Lý do tại sao winner là một ManyToManyField là một foo duy nhất có thể thuộc về một số chuyên mục, trong khi ở một thể loại duy nhất có thể có nhiều hơn một người chiến thắng do ex-aequo.)

Tôi muốn áp đặt ràng buộc tự nhiên mà một foo chỉ có thể giành chiến thắng trong danh mục nếu nó thuộc về danh mục đó. Cách hợp lý nhất để làm như vậy dường như sử dụng tham số limit_choices_to, nhưng có vẻ như với tôi rằng không thể giới hạn các lựa chọn dựa trên trường hợp hiện tại của mô hình.

tôi có thể áp đặt các hạn chế này trong một hình thức nhất định, nhưng tôi muốn tránh điều này vì hai lý do:

  • hạn chế một cách tự nhiên sống ở mức mô hình. Đó là một mối quan hệ đặc biệt mà nên luôn luôn giữ giữa hai mô hình liên quan
  • sự lựa chọn của người chiến thắng sẽ được thực hiện trong các admin, và tôi muốn để tránh việc phải tùy chỉnh các quản trị viên tạo

Có bất kỳ cách nào để áp đặt hạn chế này trong Django?

Trả lời

4

Không có cách nào để đặt ràng buộc vào trường M2M ở cấp mô hình (ví dụ: với limit_choices_to). Tuy nhiên, bạn có thể làm điều này trong biểu mẫu:

class MyForm(forms.ModelForm): 
    class Meta: 
     model = models.Category 

    def __init__(self, *args, **kwargs): 
     super(MyForm, self).__init__(*args, **kwargs) 
     if 'instance' in kwargs: 
      my_category = kwargs['instance'] 
      self.fields['winner'].queryset = my_category.category.all() 

Bạn đã nhận thấy điều đó chưa?

my_category.category.all() 

Có lẽ những gì bạn muốn là:

class Foo(models.Model): 
    name = models.CharField(max_length=30) 
    # More fields... 
    category = models.ForeignKey(
     Category, 
     related_name='participants' 
    )