newforms: generating forms from models enhancements

6 views
Skip to first unread message

Honza Král

unread,
Dec 16, 2006, 4:46:36 PM12/16/06
to django-d...@googlegroups.com
Hi all,

I would like to ask what is the status of django/newforms/models.py

there are a few things I would like to see in there (or where
appropriate) and don't know if somebody is already working on it (or
other things that would clash with this effort), or if I should give
it a try.

mainly:
- specifying a widget class when defining a model field (perhaps add a
keyword param form_widget=DefaultWidget to
django.db.models.field.Field.__init__() ? )

- allowing default to be pre-filled in a field ( I am not sure, if
this is even useful, or if people will use it, what do you think? )

- specifying a custom BaseForm to inherit from? (someone could want to
have custom forms, that override as_p() for example) in
django.newforms.models

- allowing form_for_fields() to handle 2 fields of the same name (I
don't know how to do this one - you can make the name unique, but how
to maintain

- take validator_list into consideration when constructing a formfield
(this will probably require some nasty changes to be made to the
validation framework - either add a function - FormField mapping or
use FormFields in validator_list )

Some of these things are fairly simple (widgets, BaseForm), others
require some attention and comments (default, validators, non-unique
fields).

Please let me know if my attention is better spent someplace else
(perhaps rewriting the validators to Fields) - I have some free time
at the end of the year and would like to invest some of it into django
(and especially newforms, since we have a big project comming up and
we would love to use newforms from the neginning).

Thanks for any comments you may have.
--
Honza Král
E-Mail: Honza...@gmail.com
ICQ#: 107471613
Phone: +420 606 678585

Adrian Holovaty

unread,
Dec 17, 2006, 12:25:13 AM12/17/06
to django-d...@googlegroups.com
On 12/16/06, Honza Král <honza...@gmail.com> wrote:
> there are a few things I would like to see in there (or where
> appropriate) and don't know if somebody is already working on it (or
> other things that would clash with this effort), or if I should give
> it a try.

Hi Honza,

Thanks for bringing this up, and see my comments below --

> - specifying a widget class when defining a model field (perhaps add a
> keyword param form_widget=DefaultWidget to
> django.db.models.field.Field.__init__() ? )

Yes, there should be a way to specify the widget for a field in the
model. The question is, should it be specified as a keyword argument
to the field declaration, or should it be passed in the "class Admin"?
The advantage of the second approach is that it's nicely
compartmentalized, but the advantage of the first is that it's more
compact and also would apply to non-admin forms (like the one you get
for form_for_model).

> - allowing default to be pre-filled in a field ( I am not sure, if
> this is even useful, or if people will use it, what do you think? )

I think adding a "default" parameter to newforms Field classes would
be a nice addition.

> - specifying a custom BaseForm to inherit from? (someone could want to
> have custom forms, that override as_p() for example) in
> django.newforms.models

This is an excellent idea. I've implemented it in [4220].

> - allowing form_for_fields() to handle 2 fields of the same name (I
> don't know how to do this one - you can make the name unique, but how
> to maintain

We could change the fields parameter to accept a list of (field_name,
field_instance) tuples, perhaps?

> - take validator_list into consideration when constructing a formfield
> (this will probably require some nasty changes to be made to the
> validation framework - either add a function - FormField mapping or
> use FormFields in validator_list )

I've been operating under the assumption that we would drop
validator_list from models, in favor of a model field parameter such
as "formfield", which would be a newforms.Field class object.
Thoughts?

> Please let me know if my attention is better spent someplace else
> (perhaps rewriting the validators to Fields) - I have some free time
> at the end of the year and would like to invest some of it into django
> (and especially newforms, since we have a big project comming up and
> we would love to use newforms from the neginning).

Great! I'm excited that you can continue to help, as I have really
appreciated your patches and contributions so far. Feel free to take
on any of the items mentioned in this e-mail, as long as we've all
agreed on the right way to solve the problems. Rewriting the
validators to Fields would be a much-welcomed contribution, too.
Whatever you choose, let us know so that we don't duplicate work.

Myself, I'm going to focus on newforms documentation, improving the
form_for_model() unit tests and implementing formfield() for the
remaining model Field classes.

Thanks again for your continued help on this -- we really appreciate it!

--
Adrian Holovaty
holovaty.com | djangoproject.com

Ivan Sagalaev

unread,
Dec 17, 2006, 6:23:38 AM12/17/06
to django-d...@googlegroups.com
Adrian Holovaty wrote:
> Yes, there should be a way to specify the widget for a field in the
> model. The question is, should it be specified as a keyword argument
> to the field declaration, or should it be passed in the "class Admin"?

Would it be better to specify it as and additional parameter form
form_for_model? I remember having a need to display a field differently
in different forms.

Like:

form_for_model(..., widgets = {'field_name': WidgetClass})

Honza Král

unread,
Dec 17, 2006, 7:28:48 AM12/17/06
to django-d...@googlegroups.com
On 12/17/06, Ivan Sagalaev <Man...@softwaremaniacs.org> wrote:
>
> Adrian Holovaty wrote:
> > Yes, there should be a way to specify the widget for a field in the
> > model. The question is, should it be specified as a keyword argument
> > to the field declaration, or should it be passed in the "class Admin"?
>
> Would it be better to specify it as and additional parameter form
> form_for_model? I remember having a need to display a field differently
> in different forms.

it would be nice to override it, but I IMHO in most cases it is useful
to specify it on the field-level. So when admin and generic views
start to use newforms it will be there.

But if you would want to override this when creating a Form from
fields, things would get a bit more complicated:
you would have to/be able to specify:
field itself
field name,
widget,
default value (why not, if we already have all those other params),
label,
...

where only field should be required...
perhaps this could be done by passing a dictionary with fields as keys
and either only true or a dictionary of options as value

{
Object._meta.fields[0] : True,
Object._meta.fields[1] : {
'name' : 'Custom Name',
'widget' : SuperWidget,
....
}
}

what do you think? its just a first thought


>
> Like:
>
> form_for_model(..., widgets = {'field_name': WidgetClass})
>
> >
>

Honza Král

unread,
Dec 17, 2006, 11:13:08 AM12/17/06
to django-d...@googlegroups.com
On 12/17/06, Adrian Holovaty <holo...@gmail.com> wrote:
>
> On 12/16/06, Honza Král <honza...@gmail.com> wrote:
> > there are a few things I would like to see in there (or where
> > appropriate) and don't know if somebody is already working on it (or
> > other things that would clash with this effort), or if I should give
> > it a try.
>
> Hi Honza,
>
> Thanks for bringing this up, and see my comments below --
>
> > - specifying a widget class when defining a model field (perhaps add a
> > keyword param form_widget=DefaultWidget to
> > django.db.models.field.Field.__init__() ? )
>
> Yes, there should be a way to specify the widget for a field in the
> model. The question is, should it be specified as a keyword argument
> to the field declaration, or should it be passed in the "class Admin"?
> The advantage of the second approach is that it's nicely
> compartmentalized, but the advantage of the first is that it's more
> compact and also would apply to non-admin forms (like the one you get
> for form_for_model).
>
> > - allowing default to be pre-filled in a field ( I am not sure, if
> > this is even useful, or if people will use it, what do you think? )
>
> I think adding a "default" parameter to newforms Field classes would
> be a nice addition.

I did this one - see the attached patch field_default.patch (all tests passed)

current behaviour may seem sort of strange, but its the best I could
come up with:

In [2]: from django import newforms as forms

In [3]: class MyForm( forms.Form ):
...: test_field = forms.CharField( max_length=20,
required=False, default=u'DEFAULT')
...:

In [4]: form = M
MemoryError MyForm

In [4]: form = MyForm(None)

In [5]: form.as_p()
Out[5]: u'<p><label for="id_test_field">Test field:</label> <input
id="id_test_field" type="text" name="test_field" value="DEFAULT"
maxlength="20" /></p>'

In [6]: form = MyForm({})

In [7]: form.is_valid()
Out[7]: True

In [8]: form.as_p()
Out[8]: u'<p><label for="id_test_field">Test field:</label> <input
id="id_test_field" type="text" name="test_field" value="DEFAULT"
maxlength="20" /></p>'

In [9]: form = MyForm({ 'test_field' : u''})

In [10]: form.is_valid()
Out[10]: True

In [11]: form.as_p()
Out[11]: u'<p><label for="id_test_field">Test field:</label> <input
id="id_test_field" type="text" name="test_field" maxlength="20"
/></p>'

In [12]: form.clean_data
Out[12]: {'test_field': u'DEFAULT'}

I will be glad for comments...

I would imagine poeple will want only one of these actions - pre-fill
an empty form (X)OR replace an empty value with the default

>
> > - specifying a custom BaseForm to inherit from? (someone could want to
> > have custom forms, that override as_p() for example) in
> > django.newforms.models
>
> This is an excellent idea. I've implemented it in [4220].

thanks

>
> > - allowing form_for_fields() to handle 2 fields of the same name (I
> > don't know how to do this one - you can make the name unique, but how
> > to maintain
>
> We could change the fields parameter to accept a list of (field_name,
> field_instance) tuples, perhaps?
>
> > - take validator_list into consideration when constructing a formfield
> > (this will probably require some nasty changes to be made to the
> > validation framework - either add a function - FormField mapping or
> > use FormFields in validator_list )
>
> I've been operating under the assumption that we would drop
> validator_list from models, in favor of a model field parameter such
> as "formfield", which would be a newforms.Field class object.
> Thoughts?

this is nice, can be a bit more typing though - but I have no other
(let alone better) idea... :-/


>
> > Please let me know if my attention is better spent someplace else
> > (perhaps rewriting the validators to Fields) - I have some free time
> > at the end of the year and would like to invest some of it into django
> > (and especially newforms, since we have a big project comming up and
> > we would love to use newforms from the neginning).
>
> Great! I'm excited that you can continue to help, as I have really
> appreciated your patches and contributions so far.

Glad to here this, have a look on ticket #3050 for more patches... :)

Feel free to take
> on any of the items mentioned in this e-mail, as long as we've all
> agreed on the right way to solve the problems. Rewriting the
> validators to Fields would be a much-welcomed contribution, too.
> Whatever you choose, let us know so that we don't duplicate work.

see new_fields.py for validators transformed into Fields. It is a
result of a few sed expressions (see gen_new_fields.sh ) and some
manual tweaks. I haven't tested it even for syntax errors, any help
would be welcome, especially tests and documentation (I suck at
these)...

I will continue working on those whenever I have some time (and mood ;) )

> Myself, I'm going to focus on newforms documentation, improving the
> form_for_model() unit tests and implementing formfield() for the
> remaining model Field classes.

looking forward to that

>
> Thanks again for your continued help on this -- we really appreciate it!
>
> --
> Adrian Holovaty
> holovaty.com | djangoproject.com
>
> >
>

field_default.patch
gen_new_fields.sh
new_fields.py

Gary Wilson

unread,
Dec 17, 2006, 6:57:24 PM12/17/06
to Django developers

If inheriting Fields is going to be the new validator_list, don't we
need to add some super() calls in those clean() methods?

Honza Král

unread,
Dec 17, 2006, 7:04:25 PM12/17/06
to django-d...@googlegroups.com

there are - every clean() starts with
value = ParentField.clean( value )
which should represent a super call

Gary Wilson

unread,
Dec 17, 2006, 7:28:47 PM12/17/06
to Django developers
Some more suggestions based on things that I have experienced while
recently making an application that required many forms based on
models:

- Ability to not display certain fields, mainly for when the value will
be post-filled in the view (i.e. the owner of an object being set to
the logged in user).

- Ability to override the default labels and help text, since in some
cases the labels and help text presented to an end user should not be
the same as what's seen in the admin interface (I believe the label
overriding was mentioned already, but help_text would be nice too).

- Speaking of help_text, it might be nice for the as_* methods to print
this out as well.

- Ability to add extra validation to form fields, above and beyond the
model's validation. I think this would be satisfied with the
"formfield" parameter that Adrian mentioned.

These could be satisfied by adding more parameters taking <field name>:
<value> dictionaries.

Gary Wilson

unread,
Dec 17, 2006, 7:41:14 PM12/17/06
to Django developers

Oh, and I forgot:
- Ability to override if a field is required or not. My model might
not require data for a certain field, but sometimes I want my form to
require data.

Gary Wilson

unread,
Dec 17, 2006, 8:21:36 PM12/17/06
to Django developers

But it's not the same thing. Let's say I want to make a
LowerCaseAlphaNumericField that inherits LowerCaseField and
AlphaNumericField, both of which inherit CharField. If I were to call
LowerCaseField.clean() and AlphaNumericField.clean() from my
LowerCaseAlphaNumericField.clean(), then CharField.clean() and
Field.clean() would both get called twice. If I were to use a super
call in my LowerCaseAlphaNumericField.clean(), then
LowerCaseField.clean(), CharField.clean(), and Field.clean() would get
called, but not AlphaNumericField.clean().

Everybody must use super so that all the correct methods get called and
get called only once.

I'm not sure where ComboField fits into this either. Is ComboField
supposed to be used instead of inheritance for building validators? If
so, then ComboField suffers the same fate of calling clean() methods of
inherited Fields more than once (even if super calls are used) because
ComboField.clean() simply calls every passed Field's clean() method.

Honza Král

unread,
Dec 17, 2006, 9:36:25 PM12/17/06
to django-d...@googlegroups.com

I am sorry for the confusion - this is by no way a finished file, its
just a rough sketch (if that). Please treat it as such.

>
> Everybody must use super so that all the correct methods get called and
> get called only once.
>
> I'm not sure where ComboField fits into this either. Is ComboField
> supposed to be used instead of inheritance for building validators? If
> so, then ComboField suffers the same fate of calling clean() methods of
> inherited Fields more than once (even if super calls are used) because
> ComboField.clean() simply calls every passed Field's clean() method.

ComboField would be used for the LowerCaseAlphaNumericField for
example - it would just be a combination of AlphaNumericField and
LowerCaseField, thus no extra clean() needs to be specified... and
yes, that would mean that CharField.clean() would actually get called
twice...

Reply all
Reply to author
Forward
0 new messages