#13693: error_messages for fields in Model don't carry over to ModelForm
-------------------------------------+-------------------------------------
     Reporter:  Aleks                |                    Owner:  anonymous
         Type:  New feature          |                   Status:  closed
    Component:  Forms                |                  Version:  1.4
     Severity:  Normal               |               Resolution:
     Keywords:  error_messages,      |  worksforme
  forms, models                      |             Triage Stage:  Accepted
    Has patch:  1                    |      Needs documentation:  1
  Needs tests:  1                    |  Patch needs improvement:  1
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by colegatron):

 * status:  reopened => closed
 * resolution:   => worksforme
 * needs_tests:  0 => 1
 * version:  1.2 => 1.4
 * needs_docs:  0 => 1
 * type:  Uncategorized => New feature


Comment:

 I am new to Django but I also think the DRY mantra should be aplicable to
 the error_messages inheritance from the model to the modelform.
 Perhaps by a design point of view it is not a good idea, as points Honza
 in his first comment (22 months ago), but to redefine all the fields in
 the modelform or form classes to get the error_messages (and perhaps other
 attributes) is tedious and boilerplate.
 Looking for a way to avoid this, I have find a post
 (http://blog.brendel.com/2012/01/django-modelforms-setting-any-field.html)
 which gives a very nice, easy and elegant way to do it.

 Probably that solution can be improved, but in my opinion is candidate to
 be imported as new feature in the base modelform class:

 Example of use:

 {{{
 class AuthorForm(ExtendedMetaModelForm):
     class Meta:
         model = Author
         field_args = {
             "first_name" : {
                 "error_messages" : {
                     "required" : "Please let us know what to call you!"
                 }
             },
             "notes" : {
                 "+error_messages" : {
                     "required" : "Please also enter some notes.",
                     "invalid"  : "This is not a valid note."
                 },
                 "widget" : forms.Textarea(attrs={'cols': 70, 'rows': 15}),
             }
         }
 }}}

 Extended modelform class:

 {{{
 class ExtendedMetaModelForm(forms.ModelForm):
     """
     Allow the setting of any field attributes via the Meta class.
     """
     def __init__(self, *args, **kwargs):
         """
         Iterate over fields, set attributes from Meta.field_args.
         """
         super(ExtendedMetaModelForm, self).__init__(*args, **kwargs)
         if hasattr(self.Meta, "field_args"):
             # Look at the field_args Meta class attribute to get
             # any (additional) attributes we should set for a field.
             field_args = self.Meta.field_args
             # Iterate over all fields...
             for fname, field in self.fields.items():
                 # Check if we have something for that field in field_args
                 fargs = field_args.get(fname)
                 if fargs:
                     # Iterate over all attributes for a field that we
                     # have specified in field_args
                     for attr_name, attr_val in fargs.items():
                         if attr_name.startswith("+"):
                             merge_attempt = True
                             attr_name = attr_name[1:]
                         else:
                             merge_attempt = False
                         orig_attr_val = getattr(field, attr_name, None)
                         if orig_attr_val and merge_attempt and \
                                     type(orig_attr_val) == dict and \
                                     type(attr_val) == dict:
                             # Merge dictionaries together
                             orig_attr_val.update(attr_val)
                         else:
                             # Replace existing attribute
                             setattr(field, attr_name, attr_val)

 }}}


 Hope this two years ticket can be closed with that nice solution.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/13693#comment:7>
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 post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to