简体   繁体   中英

How would I use the objects from a related Model to populate the initial value of a Field in a ModelForm?

My issue is with the 5th line below (the one with all of the question marks):

class EditProfileForm(forms.ModelForm):
    """ Base form used for fields that are always required """
    first_name = forms.CharField(label=_(u'First name'), max_length=30, required=False)
    last_name = forms.CharField(label=_(u'Last name'), max_length=30, required=False)
    language = forms.ModelMultipleChoiceField(label=_(u'Language'), queryset=Language.objects.all(), initial=VolunteerLanguage.objects.filter(volunter=??????????))
    categories = forms.ModelMultipleChoiceField(label=_(u'Categories'), queryset=TaskCategory.objects.all(), widget=forms.CheckboxSelectMultiple(), required=False)

    def __init__(self, *args, **kw):
        super(EditProfileForm, self).__init__(*args, **kw)
        self.profile = super(EditProfileForm, self).save(True)
        # Put the first and last name at the top
        new_order = self.fields.keyOrder[:-3]
        new_order.insert(0, 'first_name')
        new_order.insert(1, 'last_name')
        new_order.insert(2, 'language')
        self.fields.keyOrder = new_order

    class Meta:
        model = get_profile_model()
        exclude = ['user', 'editions', 'tasks', 'signed_up', 'language']

    def save(self, force_insert=False, force_update=False, commit=True):
        profile = super(EditProfileForm, self).save(commit=commit)
        # Save first and last name
        VolunteerLanguage.objects.filter(volunteer=profile).delete()
        for lang in self.cleaned_data['language']:
            languages = VolunteerLanguage(volunteer=profile, language=lang)
            languages.save()
        user = profile.user
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.save()

        return profile

The problem is that I cannot retrieve the objects from VolunteerLanguage (link table) as I need to pass a Volunteer object to it in order to filter it. I can do that in the save method, but not on line 5

If you want to pass an additional parameter to your form and use that value to setup a field you can do something like this:

class EditProfileForm(forms.ModelForm):

    def __init__(self, initial_volunteer, *args, **kwargs):
            super(EditProfileForm, self).__init__(*args, **kwargs)
            self.fields['language'] = forms.ModelMultipleChoiceField(
            label=_(u'Language'), 
            queryset=Language.objects.all(),
            # now you have the value you passed to use here
            initial=VolunteerLanguage.objects.filter(volunteer=initial_volunteer)
            )

If the self.profile already in your __init__ is the one you want to use you can create your field in the __init__ the same way as my example just don't pass a new value and use your self.profile instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM