On Fri, Jan 23, 2009 at 5:02 AM, catsclaw <ch...@subtlety.com> wrote: > > On Jan 22, 12:12 am, Jacob Kaplan-Moss <jacob.kaplanm...@gmail.com> > wrote: >> On Thu, Jan 22, 2009 at 4:57 PM, catsclaw <ch...@subtlety.com> wrote: >> > Well, it seems to me that makes for an *extremely* tight coupling >> > between the model and the view. >> >> I'm sorry to be so blunt, but your perception is misguided. Forms have >> no dependancy upon models, nor do models on forms, nor must views use >> forms, models, or anything, really. > > 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. I put it to you that the current setup is not in the least bit muddled. Lets go back to the original MVC definition: The Model is a domain specific representation of data. The View renders the model in a form suitable for interaction. The Controller has nothing to do with display. It exists to mediate the exchange of data between the model (a store of data) and a view (a way of presenting data). And lo - that's exactly what the Django forms framework does! 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. Now, MVC is a pattern derived from graphical user interfaces, and the pattern doesn't apply completely transparently to web-based applications. However, the deviations are fairly minor - the core concerns are all still there. You appear to be particularly concerned by the widget_attrs method on Field. I will concede that this is a slight leakage of the View into the Controller layer. However, I would draw your attention to two things: 1) Exactly 1 builtin field makes use of this - CharField - which pushes the maximum allowed length to the underlying widget only when the underlying widget is TextInput or PasswordInput. This could certainly be made more flexible, but this requires a minor tweak, not a major rebuild of the entire forms framework. 2) There is absolutely nothing that says you have to use this attribute data as-is during rendering. The fields get a list of attributes - but it's entirely up to you use all, some or none of those attributes during rendering. >> > And it's a little difficult for me to >> > understand what value there is in such a tight coupling--if I've got a >> > DateField, why can't I have it represented in an HTML page by a >> > javascript calendar pop-up, or a text box, or three select boxes >> > (month, day, and year). >> >> It's difficult to understand because you've assumed it's impossible; >> it's not. A quick google search for "django datefield select" ... > > No, no. You're missing my point. I was responding to Russell, who > said "A form contains fields ... Each > field provides a widget, which describes a HTML element that allows > that data to be collected." That description--that forms contain many > fields, and each field corresponds to a widget--isn't sufficient to > explain the relationship between forms, fields, and 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. Think of it like a magical Lego kit - Django provides a big bucket of bricks, and a big button you can press that will automatically build a multicolored brick wall. This is fine for prototyping, but the interesting results happen when someone with design talent carefully selects the color and placement of bricks and ends up with a lifesize model of a Stegosaurus. 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. This will still raise some eyebrows (for the reasons of focus I mentioned earlier), but it will raise less eyebrows than a call to rebuild the entire forms framework. >> > Plus, any time you collect a password you need to display it in a >> > form using a password input, not the stock text input. >> >> Again, this is in fact not only possible, but easy:: >> >> class MyForm(forms.Form): >> password = forms.CharField(widget=forms.PasswordInput) > > Yes, I know this. That's why I used it as an example. > This is a case where the field gets asked, during the rendering > process, "I'm drawing a PasswordInput, are there any extra attributes > I should add?" and the field adds the input length to the HTML. I'm > rather aghast that Fields are expected to know about HTML at all, let > alone be aware of all the available widgets so they can modify them. See my previous comments. The field is required to provide hints to its widget. Those hints _can_ be used as literal HTML attributes, but there is no requirement that this is the case. > A better design is to have the fields open to interrogation by > widgets. That way, a widget can ask if there's a limit on the number > of characters in this field. That way new widgets and new fields work > together, without having to know about each other ahead of time. This doesn't fix the problem, it just changes the error handling. Under the current setup, a field determines that it has something to tell the widget, and passes that information down to the widget. The widget then has the choice as to whether it uses that information; if it requires that a particular piece of data is provided (e.g., a maximum length), the widget will need to include error handling or a default to allow for fields that don't provide a maxlength hint. 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. >> Why don't we start over here: what is the problem? What did you try do >> do? What did you expect to happen? What actually happened? > > Very well. I'm trying to write a subclass of Form that knows about > Dojo forms, and will render them appropriately. To do this, I assumed > I would subclass Form (as DojoForm) and then create a widget for each > Dojo form element I wanted to use. The DojoForm would have a number > of settings relating to the form as a whole, which would alter the way > each DojoWidget rendered itself. The requirement to pass form-level attributes to the widget is the only part of this process that could pose a problem. Django's forms pretty much assume that each field can be independently rendered; the {{ form }} template element exists as a shortcut, but it's generally assumed that once you're past the prototyping phase, you will be laying out each form element by hand, using {{ form.field_name }} in your template. In order to pass form level attributes to the widgets, you would need to override BoundField, but there isn't a way to do this at the moment. Again - this is a minor customization point, not a reason to tear down the framework. 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. > When a DojoForm gets passed to a template, I could then call a > method in the head of the document that would know what statements to > place in the Javascript, and a different method in the body of the > document which would render the actual form proper. > What's the best way of doing this? Change the render() method for each widget to include the appropriate HTML, and use the Media framework to gather Javascript requirements. See django/contrib/admin/widgets.py for a selection of examples where this is done already. These widgets are used by the Django admin, and use custom JavaScript rather than Dojo to provide the pretty, but the principle should be the same. Yours, Russ Magee %-) --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---