2010-01-26 22 views
10

Khi tạo trang phẳng, tôi muốn người dùng chọn mẫu từ danh sách được xác định trước. Để giữ cho các mô hình Flatpage hoang sơ, tôi thích ChoiceField qua ModelChoiceField (sau này cung cấp PK của mẫu, nhưng tôi cần tên cho trường TEMPLATE_NAME):trường và base_fields - Django

class NewFlatpageForm(FlatpageForm): 

    template_name = forms.ChoiceField(choices = []) 
    def __init__(self, *args, **kwargs): 
     self.base_fields['template_name'].choices = ProjectTemplate.objects.values_list('path', 'name') 
     super(NewFlatpageForm, self).__init__(*args, **kwargs) 

tôi ghi đè __init__ hoặc Django populates lựa chọn tại máy chủ bắt đầu và không cập nhật danh sách sau đó.

Tôi không có bất kỳ trải nghiệm quản trị nào, nhưng tôi đã làm những việc tương tự bằng cách sử dụng thuộc tính fields khi không sử dụng quản trị viên. Tuy nhiên trong trường hợp này, tôi có một ngoại lệ nói fields không phải là một thuộc tính của biểu mẫu. __dict__ cho tôi thấy có thuộc tính base_fields và sử dụng thuộc tính. Vì vậy, tại sao sử dụng base_fields ở đây, và tại sao là fields không có mặt và cuối cùng tôi đang làm một cái gì đó hacky?

Trả lời

11

fields không tồn tại cho đến sau bạn đã gọi super. Vì vậy, chỉ cần hoán đổi thứ tự của các dòng, để super đến trước.

+0

Cảm ơn Daniel .. – shanyu

8

Bài học từ kinh nghiệm của riêng tôi: sửa đổi basefields có nghĩa là sửa đổi của bạn dính xung quanh "mãi mãi" (cho đến khi thoát ra python). Trong trường hợp của bạn, đó có thể không phải là một vấn đề, vì bạn luôn sử dụng cùng một tên trường và bạn đang thay thế giá trị của nó bằng cách gán từ ProjectTemplate ...

Trong trường hợp của tôi, tôi muốn các trường hoàn toàn khác nhau dựa trên tham số trong hàm tạo. Vì tên trường của tôi thường khác nhau, mỗi khi tôi khởi tạo một biểu mẫu, tôi đã thêm các trường mới nhưng không loại bỏ các trường này từ lần trước.

Bằng cách gọi siêu sớm (như được chỉ ra ở đây) và sau đó thực hiện thay đổi động của tôi cho self.fields thay vì self.basefields, tôi đã có thể loại bỏ vấn đề của danh sách ngày càng tăng của các trường. Bây giờ nó có ý nghĩa hoàn hảo, nhưng tôi không quen thuộc với tất cả các chi tiết cú pháp và đã hack qua thay vì cố gắng hiểu nó trước.

3

Ngoài Joe Germuska. Nếu bạn thực sự cần thay đổi biểu mẫu dựa trên yêu cầu, bạn có thể sử dụng bản in sâu để đảm bảo không có gì thay đổi theo tham chiếu:

def get_form(self, request, obj=None, **kwargs): 
    form = super(ResourceAdmin, self).get_form(request, obj, **kwargs) 
    form = copy.deepcopy(form) 

    if obj: 
     form.base_fields['email'] = EmailField(initial=obj.user.email) 
    if not request.user.is_superuser: 
     form.base_fields['user'].widget = HiddenInput(attrs={'class': 'hide_form_row'}) 

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