#20267: default form values (not just initial)
-------------------------------+--------------------------------------
     Reporter:  clime          |                    Owner:  nobody
         Type:  New feature    |                   Status:  closed
    Component:  Forms          |                  Version:  1.5
     Severity:  Normal         |               Resolution:  worksforme
     Keywords:  form, default  |             Triage Stage:  Unreviewed
    Has patch:  0              |      Needs documentation:  0
  Needs tests:  0              |  Patch needs improvement:  0
Easy pickings:  0              |                    UI/UX:  0
-------------------------------+--------------------------------------

Comment (by clime):

 Well my problem was that I have this form for filtering:


 {{{
 class CragFilter(forms.Form):
     country =
 
forms.ChoiceField(choices=Country.objects.all().order_by('name').values_list('id',
 'name'), required=False)
     crag_type = forms.MultipleChoiceField(choices=crag_types,
 initial=[str(BOULDER), str(ROUTE)], widget=forms.CheckboxSelectMultiple,
 required=False)
     order_by = forms.CharField(required=False, initial='crag')
     order_asc = forms.BooleanField(required=False, initial=True)
 }}}crag_filter = CragFilter(data)


 Now there were actually two problems. The first one was with with the
 initial value for crag_type. Filtering should be done by GET requests, I
 believe, so I simply did this in my view:

 {{{
 def crag_list(request):
     crag_filter = CragFilter(request.GET)

     if crag_filter.is_valid():
        filter_params = crag_filter.cleaned_data

     crag_list = Crag.get_objects(filter_params)

       context = {
           'crag_filter': crag_filter,
           'crag_list': crag_list,
       }
       return render(request, 'crags.html', context)

 }}}

 Seems quite natural to me. But I have found out that checkboxes in
 frontend are not checked after the initial page load (without any query
 params). And later I have found out it is because form has been bounded to
 request.GET data. But mainly the crag_list was empty because the initial
 values has been lost. So I have decided to do this in the view:

 {{{
 if request.GET:
   crag_filter = CragFilter(request.GET)
 else:
   crag_filter = CragFilter()
 }}}

 which I don't like at all but it was the simplest solution.

 But I have work on and discovered yet another problem with order_by and
 order_asc fields. These fields are not part of the frontend form (by
 graphic design and provided templates) but it seemed natural to put them
 into the backend/logic form anyway so that I can simply pass these
 parameters to model with others and then in models differentiate what to
 put as param of .filter() and what to put as a param of .order_by(). This
 approach simply makes view simpler (which is good, I think). Backend form
 does not "match" the frontend form but it was possible to do it like this
 without any javascript hacks and it all worked well. Except initial values
 because checking if request.GET is empty before passing it to the filter
 was no longer working. Basically, if querystring has not been populated,
 submitting the form trashed initial values for filter params and
 submitting the ordering trashed initial values filtering. In the end I
 needed to do something like this in view:

 {{{
       data = request.GET.copy()
       data.setlistdefault('crag_type', [str(BOULDER), str(ROUTE)])
       data.setdefault('order_by', 'crag')
       data.setdefault('order_asc', True)
       crag_filter = CragFilter(data)
 }}}

 which was really painful. Maybe there is some other option with some
 clean_[field_name] methods but that is painful too.

 Well, allright I understand that I can't expect "the initial" values to
 behave like "default values" (except I totally did when I was learning
 about forms.) but I don't understand why there is not the "default
 functionality" that would work in the same way like that one for models.
 It would cover the "initial functionality" but also would be more solid,
 robust and intuitive...basicall it would decouple frontend (rendering)
 functionality from backend (logic) functionality.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/20267#comment:2>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to