Каков наилучший способ изменить форму Django во время выполнения? - PullRequest
4 голосов
/ 23 июня 2011

Код, который я использую:

class VoteForm(forms.ModelForm):
    other_choice1 = forms.BooleanField(required=False)
    other_choice2 = forms.BooleanField(required=False)
    other_choice3 = forms.BooleanField(required=False)
    other_choice4 = forms.BooleanField(required=False)

    class Meta:
        model = Vote
        exclude = ('choice', 'other_choices',)

    def __init__(self, poll_id, *args, **kwargs):
        super(VoteForm, self).__init__(*args, **kwargs)
        p = get_object_or_404(Poll, pk=poll_id)
        choices = p.choice_set.all()
        choices_len = len(choices)
        f = ['other_choice1','other_choice2','other_choice3','other_choice4']
        for i in range(0,choices_len):
           self.fields[f[i]].label = str(choices[i])
        for i in range(choices_len,4):
           del self.fields[f[i]]

Это лучший способ изменить поля формы во время выполнения. Это похоже на взлом реализации. Какой четко определенный способ сделать это?

Спасибо, Alex

Ответы [ 2 ]

4 голосов
/ 24 июня 2011

Использовать base_fields, как описано в Обезьяна исправляет класс формы Django? :

ContactForm.another_field = forms.CharField(...)
ContactForm.base_fields['another_field'] = ContactForm.another_field

(Или BaseForm, как описано здесь http://snipt.net/danfreak/how-to-generate-a-dynamic-at-runtime-form-in-django/:

def make_contact_form(user):
    fields = { 'name': forms.CharField(max_length=50),
               'email': forms.EmailField(),
               'message': forms.CharField(widget=forms.Textarea) }
    if not user.is_authenticated:
        fields['captcha'] = CaptchaField()
    return type('ContactForm', [forms.BaseForm], { 'base_fields': fields })

)
1 голос
/ 24 июня 2011

Да, это кажется хакерским. Но причина этого в том, что ты думаешь не в том направлении. Похоже, что вам нужен отдельный флажок для каждого элемента в отношениях, и вы пытаетесь реализовать это, имея по одному BooleanField на элемент. Но это совсем не то, о чем вы должны думать - вы должны думать об одном поле, представляющем элементы в этих отношениях, и о виджете ChecbkoxMultipleSelect, который фактически отображает флажки.

...