We had some discussions during PyCon in Chicago, the biggest issue we
have with the hooks is the amount of code needed to change the widgets

we talked with Joseph about something like widget-sets, a mapping prom
either field, or perhaps field type to widgets, that could be easily
defined - the simplest way to do that seems to be a dictionary
{ 'field_name': WidgetClass, ...}

it is a special case, true, but it covers 80% of cases when people
override the get_formfield_for_dbfield, which is ALWAYS messy...

On Wed, May 28, 2008 at 8:27 PM, Simon Willison <[EMAIL PROTECTED]> wrote:
>
> We (GCap, large commercial radio company in the UK) have been
> developing against the newforms-admin branch for a few months now, and
> based on that experience I have a number of suggestions for simple
> hooks that could be added to make it easier to customise.
>
> 1. Provide a custom template for a changelist / change form
>
> You should be able to specify a custom template for those pages in
> some way on the ModelAdmin object. At the moment select_template() is
> used to allow custom templates to be specified, but that isn't nearly
> flexible enough: it forces you to name your templates according to a
> certain naming scheme (e.g. admin/events/venue/change_form.html) but
> that means that you can't offer two admin interfaces with different
> templates for editing a specific thing, which is kind of the whole
> point of newforms admin allowing you to set up more than one admin
> site. It also forces you to keep your templates in an admin/ hierarchy
> which can be a bit limiting.
>
> There are two potential solutions to this. The first is to have a
> change_form_template option on the ModelAdmin:
>
> class EventAdmin(ModelAdmin):
>    change_form_template = 'foo/bar/event_change_form.html'
>
> The other is to have the template provided by a method which can be
> over-ridden:
>
> class EventAdmin(ModelAdmin):
>    def change_form_template(self, object=None):
>        return select_template(['foo.html', 'bar.html'])
>
> Either look OK to me - the second is probably better as it lets you
> run a bit of logic to decide which template to use.
>
> Another benefit of this approach: it makes it easier to extend the
> default admin template without fear of running in to the dreaded
> template recursion problem.
>
> Custom templates for ModelAdmins is absolutely my number one request
> for newforms admin. It would make a huge number of customisations a
> great deal easier (we have a UED guy who keeps on coming up with
> genuinely good ideas for tweaks to our various admin screens).
>
> 2. Better hooks for custom form fields (esp. ForeignKey choices)
>
> Every time I write a formfield_for_dbfield method I want to strangle a
> kitten. I am not alone; this is pretty much the consensus among the
> developers I work with. There really, really needs to be a better way
> of doing per-form-field customisations.
>
> One extremely important example is being able to alter the choices in
> a ForeignKey or ManyToMany field, as discussed on this ticket:
>
> http://code.djangoproject.com/ticket/3987
>
> This is critically important because one of the big new features in
> newforms-admin is the ability to do row-level permissions, thanks to
> the extremely neat has_change_permission / has_change_permission /
> has_delete_permission hooks and the ability to over-ride the queryset
> for a changelist.
>
> Unfortunately this doesn't go quite far enough. If you're dealing with
> row level permissions ("user X can edit article Y") you also need to
> be able to restrict foreign key relationships. User X might only be
> allowed to assign an article to 4 out of the 30 categories on a site,
> for example.
>
> Ticket #3987 solves this in a reasonable way, but I'm not too keen on
> the suggested dynamic method name (dynamic_FIELDNAME_choices). I
> talked this over a bit with Stuart Langridge and we came up with the
> following:
>
> class BookAdmin(ModelAdmin):
>    ...
>    def choices_for_author(self, request, book=None):
>        user = request.user
>        if not book:
>            # Creating a new book: return queryset for author choices
> that
>            # the current user is allowed to assign
>        else:
>            # Editing an existing book; maybe do something a bit
> different?
>
> Using choices_for_FIELDNAME feels like it fits better with existing
> Django conventions (like clean_FIELDNAME in newforms).
>
> Then we thought, why not take this further? The most common things you
> do with formfield_for_dbfield are setting a custom widget and setting
> a custom formfield. So why not allow these:
>
>    def widget_for_author(...):
>        return CustomWidgetOfSomeSort()
>
>    def formfield_for_title(...):
>        return FormFieldOfSomeSort()
>
> But what if you want to reuse the same method for many different
> fields? We could provide fallback methods widget_for(self, dbfield),
> formfield_for(self, dbfield) and choices_for(self, dbfield) to cover
> that.
>
> Yes, this means adding a lot of potential methods to ModelAdmin
> (though note that since they are dynamically looked up we don't have
> to add any real new methods to the actual class itself). I think
> that's fine - it makes for an API that is clean, powerful and
> extremely easy to understand.
>
> I realise that some of the above could be mocked up just by writing a
> custom formfield_for_dbfield method without patching newforms-admin at
> all. I plan to do that as a proof of concept.
>
> 3. Make it easier to include custom CSS and JavaScript
>
> By far the easiest way to tweak the admin is with a bit of unobtrusive
> CSS and JavaScript. We're using jQuery a lot for this (to great
> effect; for example, we've got a really nice drag-and-drop reordering
> interface that was added entirely as an unobtrusive enhancement), but
> it's still a bit of a pain to add custom CSS / JS. Here's the pattern
> at the moment:
>
> class AdminFormWithMedia(forms.ModelForm):
>    class Media:
>        js = ('blah/blah/blah.js',),
>        css = {
>            all': ('blah/blah.css',)
>        }
>
> class ArticleAdmin(admin.ModelAdmin):
>    form = PageFormWithMedia
>
> That's quite a lot of boilerplate just to add some CSS and JS, and
> it's weird to be putting it on the form rather than just specifying it
> for a template (not to mention this method doesn't let you add custom
> CSS/JS to the changelist page).
>
> Solving the custom template problem above would solve this as well.
>
> A few other things we've found difficult:
>
> * Customising the admin homepage (without writing a new one from
> scratch)
> * Changing the application labels that appear in the admin homepage -
> we needed to do this and it ended up being a complete nightmare (our
> end users don't want to see an interface full of obscure terms like
> gcap_sectional_revisions).
> * Making some fields read-only in some admin screens (again,
> reasonably well addressed by easier custom widgets above)
>
> The thing is, none of these problems are particularly difficult to
> address. As it stands, newforms-admin customisation is 90% of the way
> there - adding just a few more hooks would solve almost all of the
> above issues.
>
> I would be delighted to produce patches for these, but I thought it
> best to air the ideas on the mailing list first.
>
> Cheers,
>
> Simon
>
>
> >
>



-- 
Honza Král
E-Mail: [EMAIL PROTECTED]
ICQ#: 107471613
Phone: +420 606 678585

--~--~---------~--~----~------------~-------~--~----~
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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to