On 8/14/07, Pigletto <[EMAIL PROTECTED]> wrote:
>
> > Out of interest, where do you find newforms to be inflexible? Are you
> > referring to the form_for_* convenience functions or the bulk of
> > newforms itself?
> I also found some 'inflexible' places.
>
> I had a lot of work with form_for_* methods.
> While using form_for_* methods there is only one place you
> can customize your fields/widgets: formfield_callback. I think it is
> not enough.
>
> In my case there were a lot of ForeignKey fields and I had to filter
> their queryset and change value displayed in <select> element.
> It was hard to do it. Also I didn't know where should I set that
> fields are required (I couldn't set null=True in model).
>
> Because of this I've written my own 'my_form_for_*' methods with
> additional callbacks.
> For example: callback that is called just before 'formfield' call
> (before oldform's field is changed into newform's field).
> This callback made changing queryset, required, widget class very
> easy, but it was not easy to
> write (or rather realize how this works) this stuff.

If you wanted to use the standard form_for_* functions, that sounds
like something you could solve by creating a BaseForm which overrides
__init__ (taking any extra arguments you require,.e.g. querysets which
specify data to be used to populate a field's choices), and modifies
the form's fields after the call to super(...).__init__, passing this
BaseForm into form_for_* functions using their "form" argument.

For example, I have a Job model in my application - when creating a
Job, you can either specify a reference number manually (in which case
it must be validated that no Job already has that number) or leave the
number blank to have it auto-populated with the next free reference
number.

As the number absolutely *must* be a required field, I also had a case
where I didn't want to put null=True on the field just for the sake of
a form, so I did this:

# forms/jobs.py:
from django import newforms as form
from officeaid.models import Job

class JobBaseForm(forms.BaseForm):
    def __init__(self, *args, **kwargs):
        super(JobBaseForm, self).__init__(*args, **kwargs)
        self.fields['number'].required = False

    def clean_number(self):
        if 'number' in self.cleaned_data:
            try:
                Job.objects.get(number=self.cleaned_data['number'])
                raise forms.ValidationError(u'This number is already in use.')
            except Job.DoesNotExist:
                pass
        return self.cleaned_data['number']

# views/jobs.py:
from django import newforms as form
from officeaid.forms.jobs import JobBaseForm
from officeaid.models import Job

AddJobForm = forms.form_for_model(Job,
    fields=('name', 'number', ...), form=JobBaseForm)

Jonathan.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to