They don't "have" to be replaced in a subclass in the way you showed.
Perhaps it isn't perfectly DRY, but whats so bad about naming the field
explicitly?  Anyhow, when it comes specifically to widgets, the Meta
class already has a 'widgets' attribute already that lets you specify that.

I would sooner have "smart" Meta class attributes to perform this
behavior declaratively than to have to do it at the __init__ level:

class Meta:
    title__required = False
    programs__help_text = 'Hold down Ctrl to select multiple options'
    authors__required = False
    confidential__widget = AdminYesNoWidget
    uploader__required = False
    file__widget = AdminFileWidgetWithSize

... and I don't like *that* particularly either.

Cheers,
Nate

On Thu, Apr 5, 2012 at 7:49 AM, Chris Wilson <ch...@aptivate.org> wrote:

> Hi all,
>
> I've added this as a ticket but I wanted to make sure that the core and
> forms developers have a chance to see and interact with it, so I'm posting
> it here too. You can find the ticket at: <
> https://code.djangoproject.com/ticket/18064>
>
> Currently, if I want to tweak the properties of some fields in a
> ModelForm, I have to replace them in the subclass like this:
>
> {{{
> class DocumentForm(ModelForm):
>    title =
> models.Document._meta.get_field('title').formfield(required=False)
>    programs =
> models.Document._meta.get_field('programs').formfield(required=False)
>    authors =
> models.Document._meta.get_field('authors').formfield(required=False)
>    confidential =
> models.Document._meta.get_field('confidential').formfield(widget=AdminYesNoWidget)
>    uploader =
> models.Document._meta.get_field('uploader').formfield(required=False)
>    file =
> models.Document._meta.get_field('file').formfield(widget=AdminFileWidgetWithSize)
> }}}
>
> This is very bulky to just change some properties. The problem is that the
> field copies some of its properties into weird places like the widget
> during initialisation:
>
> {{{
> class Field(object):
>    ...
>    def __init__(...)
>        ...
>        if help_text is None:
>            self.help_text = u''
>        else:
>            self.help_text = smart_unicode(help_text)
>        widget = widget or self.widget
>        if isinstance(widget, type):
>            widget = widget()
>
>        # Trigger the localization machinery if needed.
>        self.localize = localize
>        if self.localize:
>            widget.is_localized = True
>
>        # Let the widget know whether it should display as required.
>        widget.is_required = self.required
>
>        # Hook into self.widget_attrs() for any Field-specific HTML
> attributes.
>        extra_attrs = self.widget_attrs(widget)
>        if extra_attrs:
>            widget.attrs.update(extra_attrs)
>
>        self.widget = widget
> }}}
>
> If we refactored this so that all the property initialisation was done in
> setters, then we could just write:
>
> {{{
> class DocumentForm(ModelForm):
>    def __init__(...)
>        self['title'].required = False
>        self['programs'].help_text = 'Hold down Ctrl to select multiple
> options'
>        self['authors'].required = False
>        self['confidential'].widget = AdminYesNoWidget
>        self['uploader'].required = False
>        self['file'].widget = AdminFileWidgetWithSize
> }}}
>
> Which is more concise, much clearer, and does not override things
> unnecessarily.
>
> I can write the code, but first I want to:
>
> * see if any core developers object, to avoid wasting effort
> * know how to run the Django tests and which suite(s) I should be running
> * know where to put the tests.
>
> Cheers, Chris.
> --
> Aptivate | http://www.aptivate.org | Phone: +44 1223 967 838
> Future Business, Cam City FC, Milton Rd, Cambridge, CB4 1UY, UK
>
> Aptivate is a not-for-profit company registered in England and Wales
> with company number 04980791.
>
> --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To post to this group, send email to django-developers@googlegroups.com.
> To unsubscribe from this group, send email to
> django-developers+unsubscr...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/django-developers?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to