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

Reply via email to