Search code examples
python-3.xdjango-formsdjango-viewsdjango-2.2

How to pass ChoiceField choices to formset?


The name works fine, but I can figure out how to pass the list of choices in the same way. The fields for those come up blank. In debugging, the choices appear properly set up.

forms.py

class MatchSheets(forms.Form):
    """ Match sheets """
    name = forms.CharField()
    propertyuser = forms.ChoiceField(choices=(), required=False)


SheetSet = formset_factory(
    MatchSheets,
    extra=0
)

views.py

    sheets = PropSheetNames.objects.filter(owner=request.user,
                                           sponsoruser=sponsoru_id)
    props = SponsorsUsers.objects.filter(owner=request.user,
                                           id=sponsoru_id).all()

    initial_set = []
    choiceset = (((prop.id), (prop.alias)) for prop in props[0].properties_user.all())

    for sh in sheets:
        initial_set.append(
            {'name': sh.name,
             'propertyuser.choices': choiceset}
        )

    form = SheetSet(request.POST or None, initial=initial_set)

I know someone will point out this could be done better with a modelformset_factory for the whole thing, or modelselect for the propertyuser, but I ran into issues with both, and just doing it manually gave me more flexibility.


Solution

  • First, this was wrong (corrected):

    choiceset = [((prop.id), (prop.alias)) for prop in props[0].properties_user.all()]
    

    Then added this below form=

    for f in form:
            f.fields['propertyuser'].choices = choiceset
    

    Was able to take it further, defaulting the choices to the value of the name field as well:

        initial_set = []
        nameset = [prop.alias for prop in props[0].properties_user.all()]
        choiceset = [((prop.alias), (prop.alias)) for prop in props[0].properties_user.all()]
        choiceset.append(('', '----'))
    

    and then

        for f in form:
            f.fields['propertyuser'].choices = choiceset
            if f.initial['name'] is not None and f.initial['name'] in nameset:
                f.fields['propertyuser'].initial = f.initial['name']
    

    Now the user just needs to handle the mismatched pairs, and done. These were the reasons I was pushed out of using Model options, at least at my ability level.