2009-04-10 37 views
5

Hãy nói rằng tôi có một số mô hình giả tạo:Làm thế nào để Sửa Lựa chọn của ModelMultipleChoiceField

class Author(Model): 
    name = CharField() 

class Book(Model): 
    title = CharField() 
    author = ForeignKey(Author) 

Và chúng ta hãy nói rằng tôi muốn sử dụng một ModelForm cho Sách:

class BookForm(ModelForm): 
     class Meta: 
     model = Book 

đơn giản cho đến nay. Nhưng chúng ta cũng nói rằng tôi có một tấn các tác giả trong cơ sở dữ liệu của tôi, và tôi không muốn có một trường lựa chọn dài như vậy. Vì vậy, tôi muốn là để hạn chế queryset trên trường ModelMultipleChoiceField của BookForm. Hãy cũng nói rằng queryset tôi muốn không thể được chọn cho đến khi __init__, bởi vì nó dựa trên một đối số được thông qua.

Điều này có vẻ như nó có thể làm các trick:

class BookForm(ModelForm): 
    class Meta: 
     model = Book 

    def __init__(self, letter): 
     # returns the queryset based on the letter 
     choices = getChoices(letter) 
     self.author.queryset = choices 

Tất nhiên, nếu điều đó chỉ làm việc tôi sẽ không có mặt ở đây. Điều đó khiến tôi trở thành AttributeError. Đối tượng 'BookForm' không có thuộc tính 'tác giả'. Vì vậy, tôi cũng đã thử một cái gì đó như thế này, nơi tôi cố gắng ghi đè lên trường mặc định của ModelForm và sau đó thiết lập nó sau:

class BookForm(ModelForm): 
    author = ModelMultipleChoiceField(queryset=Author.objects.all()) 

    class Meta: 
     model = Book 

    def __init__(self, letter): 
     choices = getChoices(letter) 
     self.author.queryset = choices 

Mà tạo ra cùng một kết quả.

Bất kỳ ai biết cách thực hiện dự định này?

Trả lời

8

Mẫu đối tượng không có lĩnh vực của họ như là thuộc tính, bạn cần phải xem xét trong "lĩnh vực" thuộc tính, đó là một cuốn từ điển:

self.fields['author'].queryset = choices 

Nếu bạn muốn hiểu rõ những gì đang xảy ra ở đây, bạn có thể quan tâm đến this answer - đó là về Mô hình, nhưng Biểu mẫu hoạt động tương tự.

7

Mặc dù Carl chính xác về các trường, bạn cũng đang bỏ lỡ một cuộc gọi cấp siêu. Đây là cách tôi làm điều đó:

class BookForm(ModelForm): 
    author = ModelMultipleChoiceField(queryset=Author.objects.all()) 

    class Meta: 
     model = Book 

    def __init__(self, *args, **kwargs): 
     letter = kwargs.pop('letter') 
     super(BookForm, self).__init__(*args, **kwargs) 
     choices = getChoices(letter) 
     self.fields['author'].queryset = choices 
+0

Vâng, khu vực sự cố thực sự của tôi có cuộc gọi cấp siêu, nhưng tôi đã bỏ qua nó cho ví dụ này. – Brian

+0

Đủ công bằng. Tôi sẽ để điều này cho bất kỳ ai đi lang thang vào câu hỏi này vì mục đích tham khảo, tôi đoán vậy. –

+1

Chắc chắn. Điều quan trọng là phải thấy rằng siêu() .__ init __() cần phải xảy ra trước khi truy cập vào các trường. – Brian

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