Dear Django group,

I would like to show users a form that they can use to customize the view, for 
example a ChoiceField from which the year of the report can be chosen. It seems 
straightforward to use a forms.Form to handle the request.GET data:


from django import forms

class JahrAuswahl(forms.Form):
    year = forms.ChoiceField(required=False, choices=[(j, j) for j in 
range(2018, 2021)])

    def clean_year(self):
        y = self.cleaned_data['year']
        if not y:
            # Set a "default" value here.
            y = 2019
        print('Year:', y)
        return y


However, the problem is with default values. Please consider this:


>>> year_form = JahrAuswahl({'year': 2018})   # Provide explicit data.
>>> print(year_form)
Year: 2018             # from JahrAuswahl.clean_year()
<tr><th><label for="id_year">Year:</label></th><td><select name="year" 
id="id_year">
  <option value="2018" selected>2018</option>    # Just as expected!
  <option value="2019">2019</option>
  <option value="2020">2020</option>
</select></td></tr>


>>> year_form = JahrAuswahl({})    # Data is empty now, need default values!
>>> print(year_form)
Year: 2019             # JahrAuswahl.clean_year() provides a default value.
<tr><th><label for="id_year">Year:</label></th><td><select name="year" 
id="id_year">
  <option value="2018">2018</option>
  <option value="2019">2019</option>   # BUT it doesn't make it back into 
year_form.data !
  <option value="2020">2020</option>
</select></td></tr>


Well, the problem is that with {} (that is, request.GET == {}), we get default 
values in year_form.cleaned_data, but we cannot use year_form in the template 
context to render the form fields.
Some work-around might be to use the year_form.cleaned_data to initialize a new 
JahrAuswahl instance:


>>> year_form = JahrAuswahl(year_form.cleaned_data)   # HACK!?
>>> print(year_form)
Year: 2019
<tr><th><label for="id_year">Year:</label></th><td><select name="year" 
id="id_year">
  <option value="2018">2018</option>
  <option value="2019" selected>2019</option>    # ok!
  <option value="2020">2020</option>
</select></td></tr>


But this feels like a hack and really not like the proper way to do this.
How can I solve this problem in an elegant Django manner?

Best regards,
Carsten


-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/07c57b13-a488-8a9d-5146-8aaa4b60fdd2%40cafu.de.
For more options, visit https://groups.google.com/d/optout.

Reply via email to