On Jan 22, 11:53 pm, Russell Keith-Magee <freakboy3...@gmail.com>
wrote:
> On Fri, Jan 23, 2009 at 5:02 AM, catsclaw <ch...@subtlety.com> wrote:
> >   I could have been clearer.  I'm not talking about Django Models
> > here; I'm talking about models, views, and controllers from the Model-
> > View-Controller design pattern.  Django widgets would correspond to
> > views, while Django forms would correspond to models.  In the current
> > architecture, this division is very muddled; I suggested reducing the
> > interdependency and adding a FormRenderer class; that would allow the
> > display elements (widgets) to be handled by a display controller (a
> > form renderer) while the model elements (fields) were handled by a
> > model controller (the form).
>
> Again, either I've misunderstood you, or you don't understand how MVC
> works. Your usage of terms like "model controller" and "display
> controller" certainly serve to confuse matters nicely.

    Yeah, I shouldn't talk in shorthand.  And my conception of how
this probably ought to work, in a perfect universe, is not only
evolving as I talk about it, but is kind of secondary to the point I'm
trying to make, which is that Django's form classes don't separate the
roles cleanly.
    My understanding of MVC is colored from my work with Java, which
used a modified version for their UI framework.  There, the View and
Controller are coupled, but divorced from the Model.

> The Form (model) holds a block of form data.
>
> The Widget (view) describes how to render form elements.
>
> The Field (controller) provides a way to extract data from the user
> interface (i.e., process raw blocks of text from a HTTP POST) and
> convert them into data suitable for storage in the model.

   But it doesn't work like that in practice.  The Form contains raw
HTML in its implementation (in the as_p method, for example) and
contains hardcoded links (through the BoundField class) to widgets to
use for a TextInput or Textarea.  A Field contains rules for
validating itself, while the Form has rules (although not many in the
base class) for validating groups of fields.  Fields also contain HTML
to inject into widgets.

> > And it's
> > a very limiting conception of what the form functionality ought to do
> > for Django as well.
>
> I fail to see why - but this might be a matter of misunderstanding of
> scope. Django's forms framework makes claims as a HTTP data
> manipulation tool with some minor sideline capabilities as a HTML
> layout tool. For any non-trivial, post-prototype application, I would
> expect the web designer to have much more control over form layout
> than Django's basic form renderer.

    Sure, but that's the point.  If I had a trivial application, I
wouldn't *need* a framework to help.  The web designer should have
control over form layout.  But as it is, I can't very easily provide
that as a programmer.  And saying "draw this field over here" through
{{ form.field_name }} doesn't let me muddle about with the attributes
set on that field as a web designer.

> Coming up with perfect automated and customizable form layout has not
> historically been a core concern of Django - simply because it is
> impossible to well in an automated way. As a result, there hasn't been
> much focus placed on layout of _forms_.
>
> If this is the feature you're looking for (and it sounds like it might
> be) then sure - there is room for improvement. However - again - this
> could be accommodated without a wholesale teardown of the forms
> framework. What you're calling for is a refactor of
> Form._html_output() to allow for easier customization of form output.

   I never called for a wholesale teardown of the forms framework.
All I asked was "Is there any work being done to clean up the way
Django creates forms?"  In all the digging around I've done, I'd make
the following suggestions:

   1) Define some "standard" attributes for fields (like "max_length",
"max_value", "required") and document them.  Similarly, document the
python type each field stores its value internally as, and what types
its clean() method will accept.  Maybe this exists somewhere, but I've
been looking directly at the code, and it's not there.
   2) Delete (or heavily deprecate) the Field.widget_attrs method.
Widgets are expected to interrogate their associated Fields for this
information.
   3) Refactor the Form class into a Form class and a FormRenderer
class.  The FormRenderer takes a Form and provides an HTML layout.
The Form doesn't know any HTML, but is otherwise responsible for
everything it currently is.
   4) Change widgets (or, for backward compatibility, add an
"advanced" rendering method) which accepts a Field or group of Fields
(BoundField(s)?) and some other standard details from the FormRenderer
(value?  id?  name?) and produces the appropriate HTML.  Widgets can
interrogate their Field(s) for the standard attributes from #1, and
include client-side validation rules where appropriate.

   In this architecture, Forms are responsible for managing and
coordinating groups of Fields.  FormRenderers are responsible for
managing and coordinating groups of Widgets.  HTML is confined to the
FormRenderers and Widgets.  Forms and Fields are still responsible for
validating data on the server side.  On the client side, validation is
optional, but available (as Widgets can check for rules on Fields).
   As far as I can see, that shouldn't have especially far-reaching
implications for the existing code.  I certainly don't have the
experience with Django to be sure that's true.  But it does make
significantly more sophisticated UIs available, in a straight-forward
way, though the basic Django form mechanism.

> Under your proposal, the widget that needed to know the maximum length
> could interrogate the field to find out the allowed length... but
> would need to include error handling or a default for fields that
> don't provide a maxlength hint.

   I really don't see what the widget would need to do beyond "if
getattr(field, 'max_length', None): attr['maxLength'] =
field.max_length".  And if the widget ignores it, all that happens is
an overlong value gets passed to the server and rejected as an error
on the server side.

> However, before we (as a framework) go down the path to this sort of
> customization, I would be interested to know what sort of form-level
> attributes are required by every widget on a form.

   "class" settings, for one.  I've got a login box that usually
appears in the upper-right corner of the site, but sometimes appears
in the center of the page; reusing the form but altering the class
attributes so the one in the middle of the page is displayed in a
larger font would be nice.  And it would be very nice to set some form-
level validation logic (ensure either X exists or Y exists, but not
both) and have that hooked up automatically.  That's within spitting
distance of the changes I suggested.

-- Chris

PS. I didn't see any responses to my question about whether there was
an way for a widget to know if it was being asked to render a required
field or not.  I asked because it doesn't seem there's an easy way.
I've got a hack to work around it--I've got hacks which work around
*everything* I've mentioned above--but hacks are hacks; they're ugly,
complicated, fragile, and this seemed like useful functionality for
the main codebase to support.  That's why I asked about the form
architecture in the first place.
--~--~---------~--~----~------------~-------~--~----~
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