1
votes

I have a Django form with a field called ipts which by default has the content choices=(('', '-'*20),).

In the UpdateView I extend this list with more options. Thus, in the get_context_data I get the form and extend that list.

choices = form.fields['ipts'].choices
choices = choices.extend( [('IPTS-123', 'IPTS-454545'),] )

To make sure the choices was well populated, in the render_to_response method I print the form.fields['ipts'].choices and I have what I was expecting:

[('', '--------------------'), ('IPTS-123', 'IPTS-454545')]

However the template is not populated with these choices! Just the initial value is available for selection: ('', '--------------------')

Any ideas how to extend the choices field in a Class Based View?

Suggestions are welcome. Thanks.

Edit:

Here the view code:

class ProfileReductionUpdate(LoginRequiredMixin, SuccessMessageMixin,
                             UpdateView):
    '''

    '''
    model = UserProfile
    form_class = UserProfileReductionForm
    template_name = 'users/profile_reduction_form.html'
    # fields = '__all__'
    success_url = reverse_lazy('index')
    success_message = "Your Profile for the Reduction was updated successfully."

    def get(self, request, *args, **kwargs):
        print("*** get")

        return super(ProfileReductionUpdate, self).get(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        print("*** get_context_data")

        context = super(ProfileReductionUpdate, self).get_context_data(**kwargs)

        from pprint import pprint
        # pprint(context)
        import copy
        form = context['form']
        print("Form:")
        pprint(form)

        choices = form.fields['ipts'].choices
        choices = choices.extend( [('IPTS-123', 'IPTS-454545'),] )

        pprint(form.fields['ipts'].choices)

        # form.fields['ipts'].choices = choices

        context['form'] = form
        pprint(context['form'].fields['ipts'].choices)
        return context

    def render_to_response(self, context, **response_kwargs):

        print("*** render_to_response")
        from pprint import pprint
        pprint(context)
        pprint(response_kwargs)


        form = context['form']
        print("Form:")
        pprint(form)
        print("Form ipts choices:")
        pprint(form.fields['ipts'].choices)
        pprint(form.fields['ipts']._choices)

        # pprint(dir(form.fields['ipts']))

        return super(ProfileReductionUpdate, self).render_to_response(context, **response_kwargs)

Here the output:

*** get
[22/Nov/2017 10:22:14] DEBUG [server.apps.users.models:60] QuerySet
*** get_context_data
Form:
<UserProfileReductionForm bound=False, valid=Unknown, fields=(ipts;experiment)>
[('', '--------------------'), ('IPTS-123', 'IPTS-454545')]
[('', '--------------------'), ('IPTS-123', 'IPTS-454545')]
*** render_to_response
{'form': <UserProfileReductionForm bound=False, valid=Unknown, fields=(ipts;experiment)>,
 'object': <UserProfile: rhf>,
 'userprofile': <UserProfile: rhf>,
 'view': <server.apps.users.views.ProfileReductionUpdate object at 0x7f0d29d14b70>}
{}
Form:
<UserProfileReductionForm bound=False, valid=Unknown, fields=(ipts;experiment)>
Form ipts choices:
[('', '--------------------'), ('IPTS-123', 'IPTS-454545')]
[('', '--------------------'), ('IPTS-123', 'IPTS-454545')]

Edit 2:

Form:

class UserProfileReductionForm(forms.ModelForm):
    '''
    '''
    def __init__(self, *args, **kwargs):
        super(UserProfileReductionForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper(self)
        self.helper.form_class = 'form-horizontal'

        self.helper.layout.append(Submit('submit', 'Save'))
        self.helper.layout.append(Button('cancel', 'Cancel',
                                         css_class='btn-default',
                                         onclick="window.history.back()"))
    class Meta:
        model = UserProfile
        # exclude = ['user']
        fields = ['ipts', 'experiment']

Model:

ipts = models.CharField(
        "Integrated Proposal Tracking System (IPTS)",
        max_length=20,
        blank=True,
        choices=(('', '-'*20),)
1
Can we see your template ?scharette
And the rest of the view code.Daniel Roseman
The template is simple I tried both {% crispy form %} and {% csrf_token %} {{ form }} with similar results.RicLeal
I just posted my View code that I'm using for testing.RicLeal
This needs to be done on the form class. Can you add your current form?dkarchmer

1 Answers

0
votes

OK! I figured it out!

The field to populate is: form.fields['ipts'].widget.choices

and not: form.fields['ipts'].choices

Hope it helps others!