2010-06-02 37 views
12

Tôi muốn tạo các nhãn động cho một biểu mẫu.ModelChoiceField và tôi tự hỏi làm thế nào để làm điều đó. Tôi có lớp mẫu dưới đây:Các hình thức Django: cách tạo động các nhãn ModelChoiceField

class ProfileForm(forms.ModelForm): 

    def __init__(self, data=None, ..., language_code='en', family_name_label='Family name', horoscope_label='Horoscope type', *args, **kwargs): 
     super(ProfileForm, self).__init__(data, *args, **kwargs) 

     self.fields['family_name'].label = family_name_label 
     . 
     . 
     self.fields['horoscope'].label = horoscope_label 
     self.fields['horoscope'].queryset = Horoscope.objects.all() 

    class Meta: 
     model = Profile 

    family_name = forms.CharField(widget=forms.TextInput(attrs={'size':'80', 'class': 'contact_form'})) 
    . 
    . 
    horoscope = forms.ModelChoiceField(queryset = Horoscope.objects.none(), widget=forms.RadioSelect(), empty_label=None) 

Các nhãn mặc định được xác định bởi các unicode chức năng quy định trong định nghĩa hồ sơ. Tuy nhiên, nhãn cho các nút radio được tạo bởi ModelChoiceField cần phải được tạo động.

Đầu tiên tôi nghĩ rằng tôi có thể chỉ đơn giản là ghi đè ModelChoiceField như được mô tả trong tài liệu Django. Nhưng điều đó tạo ra các nhãn tĩnh. Nó cho phép bạn xác định bất kỳ nhãn nào nhưng khi lựa chọn được thực hiện, lựa chọn đó đã được sửa.

Vì vậy, tôi nghĩ rằng tôi cần phải thích ứng thêm cái gì đó để init như:

class ProfileForm(forms.ModelForm): 

    def __init__(self, data=None, ..., language_code='en', family_name_label='Family name', horoscope_label='Horoscope type', *args, **kwargs): 
     super(ProfileForm, self).__init__(data, *args, **kwargs) 

     self.fields['family_name'].label = family_name_label 
     . 
     . 
     self.fields['horoscope'].label = horoscope_label 
     self.fields['horoscope'].queryset = Horoscope.objects.all() 
     self.fields['horoscope'].<WHAT>??? = ??? 

Bất cứ ai có bất kỳ ý tưởng làm thế nào để xử lý này? Bất kỳ trợ giúp sẽ được đánh giá rất nhiều.


Tôi đã tìm thấy điều gì đó nhưng tôi không biết đó có phải là giải pháp tốt nhất hay không. Tôi thêm vài thứ vào init phần của lớp ProfileForm như sau:

class ProfileForm((forms.ModelForm): 

    def __init__(self, data=None, ..., language_code='en', family_name_label='Family name', horoscope_label='Horoscope type', *args, **kwargs): 
    super(ProfileForm, self).__init__(data, *args, **kwargs) 

     # this function is added 
     def get_label(self, language_code): 
      """ 
      returns the label in the designated language, from a related object (table) 
      """ 
      return HoroscopeLanguage.objects.get(horoscope=obj, language__language_code=language_code).horoscope_type_language 

     self.fields['family_name'].label = family_name_label 
     . 
     . 
     self.fields['horoscope'].queryset = Horoscope.objects.all() 
     self.fields['horoscope'].label_from_instance = lambda obj: "%s: Euro %.2f" % (HoroscopeLanguage.objects.get(horoscope=obj, language__language_code=language_code).horoscope_type_language, obj.price) 
     . 
     . 
     """ 
     The next code also works, the lambda function without the get_label function 
     """ 
     self.fields['horoscope'].label_from_instance = lambda obj: "%s: Euro %.2f" % (obj.horoscope_type, obj.price) 
     . 
     . 
     """ 
     But this code doesn't work. Anyone? 
     """ 
     self.fields['horoscope'].label_from_instance = get_label(obj, language_code) 
+0

Ý của bạn là "các nhãn mặc định được định nghĩa trong hàm' unicode' được chỉ định trong định nghĩa _Horoscope_ " ? –

Trả lời

9

Bạn có thể sử dụng một ModelChoiceField và sau đó thay đổi các lựa chọn trong bạn ProfileForm.__init__ động, ví dụ như (giả định rằng nó đã là một ModelChoiceField):

horoscopes = Horoscope.objects.all() 
self.fields['horoscope'].choices = [(h.pk, h.name) for h in horoscopes] 

h.name trong ví dụ này sẽ được sử dụng làm nhãn của lựa chọn!

+0

Khi tôi thử giải pháp của bạn, tôi nhận được lỗi: "Chọn một lựa chọn hợp lệ. Lựa chọn đó không phải là một trong những lựa chọn có sẵn." Tôi e rằng giải pháp của bạn không hoạt động. Về cơ bản mô hình Profile đã định nghĩa một tử vi quan trọng nước ngoài và một cá thể hồ sơ dự kiến ​​một cá thể của mô hình Tử vi, không chỉ là một số nguyên h.pk. – Henri

+0

Vâng, tôi có nghĩa là "các nhãn mặc định được định nghĩa trong hàm unicode được định nghĩa trong định nghĩa Horoscope" – Henri

+0

Xin lỗi tôi đã nhầm một cái gì đó ở đây, nó có thể làm việc với một ChoiceField bình thường, nhưng xem giải pháp khác của tôi với sub-classing ModelChoiceField! –

7

Bạn có thể làm lớp trường mẫu riêng của bạn và ghi đè lên các phương pháp mà tạo ra nhãn:

class MyChoiceField(ModelChoiceField): 
    def label_from_instance(self, obj): 
     # return your own label here... 
     return smart_unicode(obj) 

sử dụng nó trong hình thức của bạn giống như bạn đã làm với các ModelChoiceField:

horoscope = MyChoiceField(queryset = .....) 
+0

Có và đó cũng là những gì tôi đã viết trong câu hỏi ban đầu của tôi. Điều này tạo ra các nhãn thay thế nhưng nhãn STATIC. Xem nhận xét của tôi mà đọc "Đầu tiên tôi nghĩ rằng tôi chỉ đơn giản có thể ghi đè ModelChoiceField như mô tả trong tài liệu Django ..." – Henri

3

Trên thực tế các ví dụ về mã cuối cùng chứa lỗi phải là:

# this function is added 
def get_label(obj): 
    return '%s: Euro %.2f' % (HoroscopeLanguage.objects.get(horoscope=obj, language__language_code=language_code).horoscope_type_language, obj.price) 
. 
. 
. 

self.fields['horoscope'].label_from_instance = get_labels 

Sau đó, nó hoạt động . Không có sự khác biệt trong việc sử dụng 'lambda obj: ...' hoặc 'def get_label (obj): ...'

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