Whoops, I referenced the docs for the Model save() function, not the
ModelForm save() function. The signatures should be updated:

def save(self, commit=True):

rather than:

def save(self, *args, **kwargs):

The super() call would also need to be modified accordingly:

def save(self, commit=True):
        do_something_with_extra_fields()
        super(ModelFormMixin, self).save(commit=commit) # Call the "real"
save() method.

https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#the-save-method

-James


On Sun, Nov 16, 2014 at 12:31 AM, James Schneider <jrschneide...@gmail.com>
wrote:

> I understand that the the 'extra fields' are not part of the main model.
> However, without either providing a save() method definition somewhere,
> those fields will never be saved. Take the example I posted previously:
>
> class ModelFormMixin(forms.ModelForm):
>     extra_field_1 = forms.CharField(required=False)
>     extra_field_2 = forms.CharField(required=False)
>
>     class Meta:
>         fields = ('extra_field_1', 'extra_field_2')
>
> class ModelFormA(ModelFormMixin):
>
>     class Meta(ModelFormExtraFields.Meta):
>         model = ModelA
>         fields = ModelFormExtraFields.Meta.fields + ('email', 'blah')
>
>
> I've renamed the ModelForm containing the extra fields to ModelFormMixin
> to make it easier to distinguish, and removed the field definitions in
> ModelFormA since they aren't needed if those fields are defined on the
> model itself. If you copy/pasted the example above, created a template with
> a "<form method=post>{{form.as_p}}{% csrf_token %}<button
> type='submit'>Submit</button></form>" in it (or something to that effect),
> you would see a working form with all 4 fields mentioned above
> (extra_field_1, extra_field_2, email, and blah).
>
> If you were to submit that form, only the values entered for email and
> blah will be saved to ModelA. The two extra_field_* fields would be
> discarded/ignored, since they are not part of ModelA.
>
> You would need to define a save() method within the mixin in order to
> actually do anything with those fields (assuming it would be the same
> action every time, whether it is saving the values to another model in the
> database, sending an email, displaying a message, etc.). So, your mixin
> should really look like this:
>
> From:
> https://docs.djangoproject.com/en/dev/topics/db/models/#overriding-model-methods
>
> class ModelFormMixin(forms.ModelForm):
>     extra_field_1 = forms.CharField(required=False)
>     extra_field_2 = forms.CharField(required=False)
>
>     class Meta:
>         fields = ('extra_field_1', 'extra_field_2')
>
>     def save(self, *args, **kwargs):
>         do_something_with_extra_fields()
>         super(ModelFormMixin, self).save(*args, **kwargs) # Call the
> "real" save() method.
>
>
> This way, when the save() method is executed on ModelFormA, it will use
> the inherited save() method from your Mixin, which will do something with
> your extra_fields, and will call the save() method from the ModelForm
> class, which will ultimately save the fields related to ModelA.
>
> To answer your question, you probably could add the fields via the
> __init__() method, but that only makes the fields available for display in
> the form object, you would still have the issue of the values from the
> extra fields being saved once a submitted form is processed. With the
> strategy above, you would write the Mixin once, and have your ModelForms
> inherit from it, and update the Meta.fields to include the fields from the
> Mixin. This is, of course, assuming that the same action will be taken on
> the extra fields every time, otherwise you'll need to override save() on
> the ModelFormA class, and add the custom actions for the extra fields
> there.
>
> I guess the key take-away is that there is more to it than simply adding
> the field to the form so it can be displayed. You also need to determine
> how to process the fields after they are submitted.
>
> Hope that clarifies rather than confuses.
>
> -James
>
>
>
>
> On Sat, Nov 15, 2014 at 11:43 AM, Michael <michael.palumb...@gmail.com>
> wrote:
>
>> Thanks James.
>>
>> Maybe I did not well mention that the extra fields are not fields of the
>> Model. I do not want Django to try to save them in the model.
>> Also, I did not make FormA inherits from forms.ModelForm because there is
>> no Model to define and I want to use these extra fields with any type of
>> forms: ModelForm as well as normal Forms.
>>
>> Is there an issue to add them in the __init__ method?
>>
>>
>> Thanks
>>
>>
>>
>> Le samedi 15 novembre 2014 13:41:23 UTC-6, Michael a écrit :
>>
>>> Maybe I did not well mention that the extra fields are not fields of the
>>> Model.
>>> Also, I did not make FormA inherits from forms.ModelForm because there
>>> is no Model to define and I w
>>>
>>>
>>>
>>> Le samedi 15 novembre 2014 02:41:11 UTC-6, James Schneider a écrit :
>>>>
>>>> "Why does the following not give a final model form with 3 fields?
>>>> The two extra fields are not available. If I move them directly into
>>>> the model form, it works but I wanted to declare these fields in a separate
>>>> form because I plan on reusing them in several forms.
>>>> Is there a way to do that?"
>>>>
>>>> I also meant to answer this: The parent form with the 'extra' fields
>>>> needs to inherit from forms.ModelForm, not just forms.Form, otherwise the
>>>> child ModelForm is unhappy. You would also need to update the fields value
>>>> in Meta to include the fields from the parent form, but my example shows
>>>> that.
>>>>
>>>> Also, I didn't test this, but you may need to declare a save() function
>>>> in the parent form, otherwise your two fields will not be saved because
>>>> Django has no idea what to do with them. If these extra fields are going to
>>>> be saved using the same model as the rest of the model form, you would be
>>>> better off with inheriting from abstract models and leaving the modelform
>>>> alone.
>>>>
>>>> -James
>>>>
>>>> On Sat, Nov 15, 2014 at 12:25 AM, James Schneider <jrschn...@gmail.com>
>>>> wrote:
>>>>
>>>>> I think you're overcomplicating things. Check this out:
>>>>>
>>>>> https://docs.djangoproject.com/en/dev/topics/forms/
>>>>> modelforms/#form-inheritance
>>>>> http://chriskief.com/2013/06/30/django-form-inheritance/
>>>>>
>>>>> Try this:
>>>>>
>>>>> class ModelFormExtraFields(forms.ModelForm):
>>>>>     extra_field_1 = forms.CharField(required=False)
>>>>>     extra_field_2 = forms.CharField(required=False)
>>>>>
>>>>>     class Meta:
>>>>>         fields = ('extra_field_1', 'extra_field_2')
>>>>>
>>>>> class ModelFormA(ModelFormExtraFields):
>>>>>     email = forms.CharField(required=False)
>>>>>     blah = forms.CharField(required=False)
>>>>>
>>>>>     class Meta(ModelFormExtraFields.Meta):
>>>>>         model = ModelA
>>>>>         fields = ModelFormExtraFields.Meta.fields + ('email', 'blah')
>>>>>         # or as the last fields
>>>>>         #fields = ('email', 'blah') + ModelFormExtraFields.Meta.fields
>>>>>
>>>>> I don't even really think the Meta class in ModelFormA even needs to
>>>>> inherit directly, so just having a straight Meta: class may save some
>>>>> keystrokes, but I didn't test that.
>>>>>
>>>>> -James
>>>>>
>>>>>
>>>>> On Fri, Nov 14, 2014 at 6:15 AM, Michael Palumbo <
>>>>> michael....@gmail.com> wrote:
>>>>>
>>>>>> Thanks for your response James.
>>>>>> I am not well familiar with the metaclasses, I do not really see how
>>>>>> to do it.
>>>>>>
>>>>>> What do you think of adding the fields in the init this way?
>>>>>>
>>>>>> extra_fields = {'extra1': forms.CharField(required=False), 'extra2':
>>>>>> forms.CharField(required=False)}
>>>>>>
>>>>>> class ModelFormA(forms.ModelForm):
>>>>>>     def __init__(self, *args, **kwargs):
>>>>>>         super(ModelFormA, self).__init__(*args, **kwargs)
>>>>>>         for name, field in extra_fields.iteritems():
>>>>>>             self.fields[name] = field
>>>>>>
>>>>>> Thanks
>>>>>>
>>>>>>
>>>>>> On Thu, Nov 13, 2014 at 11:38 PM, James Schneider <
>>>>>> jrschn...@gmail.com> wrote:
>>>>>>
>>>>>>> Modify your Meta class to include the extra fields on the model
>>>>>>> form. The Meta classes are not inherited.
>>>>>>>
>>>>>>> You may also need to override the save() method on your model form
>>>>>>> to actually save the contents of those extra fields in the inherited 
>>>>>>> form.
>>>>>>>
>>>>>>> -James
>>>>>>> On Nov 13, 2014 6:32 PM, "Michael" <michael....@gmail.com> wrote:
>>>>>>>
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> Why does the following not give a final model form with 3 fields?
>>>>>>>> The two extra fields are not available. If I move them directly
>>>>>>>> into the model form, it works but I wanted to declare these fields in a
>>>>>>>> separate form because I plan on reusing them in several forms.
>>>>>>>> Is there a way to do that?
>>>>>>>>
>>>>>>>> class FormA(forms.Form):
>>>>>>>>     extra_field_1 = forms.CharField(required=False)
>>>>>>>>     extra_field_2 = forms.CharField(required=False)
>>>>>>>>
>>>>>>>> class ModelFormA(FormA, forms.ModelForm):
>>>>>>>>     class Meta:
>>>>>>>>         model = ModelA
>>>>>>>>         fields = ['email']
>>>>>>>>
>>>>>>>> Thanks
>>>>>>>> Mike
>>>>>>>>
>>>>>>>> --
>>>>>>>> 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...@googlegroups.com.
>>>>>>>> To post to this group, send email to django...@googlegroups.com.
>>>>>>>> Visit this group at http://groups.google.com/group/django-users.
>>>>>>>> To view this discussion on the web visit
>>>>>>>> https://groups.google.com/d/msgid/django-users/53753989-
>>>>>>>> 9f3b-4a46-b96a-5edf7d7ccd69%40googlegroups.com
>>>>>>>> <https://groups.google.com/d/msgid/django-users/53753989-9f3b-4a46-b96a-5edf7d7ccd69%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>>>>>> .
>>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>>
>>>>>>>  --
>>>>>>> You received this message because you are subscribed to a topic in
>>>>>>> the Google Groups "Django users" group.
>>>>>>> To unsubscribe from this topic, visit https://groups.google.com/d/
>>>>>>> topic/django-users/cwTbH2F7kZM/unsubscribe.
>>>>>>> To unsubscribe from this group and all its topics, send an email to
>>>>>>> django-users...@googlegroups.com.
>>>>>>> To post to this group, send email to django...@googlegroups.com.
>>>>>>> Visit this group at http://groups.google.com/group/django-users.
>>>>>>> To view this discussion on the web visit
>>>>>>> https://groups.google.com/d/msgid/django-users/CA%2Be%
>>>>>>> 2BciW0NwTDLRKZH9D5nPOCQfbqpen6ng_EH24B6bJ6d-xdUA%40mail.gmail.com
>>>>>>> <https://groups.google.com/d/msgid/django-users/CA%2Be%2BciW0NwTDLRKZH9D5nPOCQfbqpen6ng_EH24B6bJ6d-xdUA%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>>>>> .
>>>>>>>
>>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>>
>>>>>>
>>>>>>  --
>>>>>> 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...@googlegroups.com.
>>>>>> To post to this group, send email to django...@googlegroups.com.
>>>>>> Visit this group at http://groups.google.com/group/django-users.
>>>>>> To view this discussion on the web visit https://groups.google.com/d/
>>>>>> msgid/django-users/CALa-rBzc17qzBHBB3m6MkVR0nv3FchjpOD
>>>>>> yd_KAsQnTju9S5%3Dg%40mail.gmail.com
>>>>>> <https://groups.google.com/d/msgid/django-users/CALa-rBzc17qzBHBB3m6MkVR0nv3FchjpODyd_KAsQnTju9S5%3Dg%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>>>>> .
>>>>>>
>>>>>> For more options, visit https://groups.google.com/d/optout.
>>>>>>
>>>>>
>>>>>
>>>>  --
>> 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 http://groups.google.com/group/django-users.
>> To view this discussion on the web visit
>> https://groups.google.com/d/msgid/django-users/b2d550c8-1104-4f81-9382-2b80fea7ae29%40googlegroups.com
>> <https://groups.google.com/d/msgid/django-users/b2d550c8-1104-4f81-9382-2b80fea7ae29%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
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 http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/CA%2Be%2BciVaL-2hy5F%3Dz%3D11%3DxxywVuQZB0PM0-%3DQcWfSTXq2jcsYQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to