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 -~----------~----~----~----~------~----~------~--~---