1

I'm using Django 1.4 and Grappelli

I need an admin add page that is totally different from the change page on the same model. Different fieldsets, different readonly_fields (actually none for add), different inlines (actually none for add). And when it's submitted I need to direct it off to a factory function instead of going down the normal create path. But I need it to look and act like an admin page, and I particularly need foreign key selectors like I'd get on a normal admin page.

I tried messing around with get_readonly_fields and friends for a while but get_inline_instances is 1.5 only and I couldn't find another hook for removing the inlines.

Then I tried replacing the view and the form using get_urls but I couldn't figure out what needed to go into the context to make the template render.

I also tried messing with get_form, but the ModelAdmin still expects the form to have the same fields.

Is one of these heading in the right direction? does anyone know what I need to do?

Gordon Wrigley
  • 11,015
  • 10
  • 48
  • 62

2 Answers2

0

You can just override the admin form by setting form attribute of ModelAdmin to your own form class.

For example See: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.form

class PersonForm(forms.ModelForm):

    class Meta:
        model = Person
        exclude = ['name']

class PersonAdmin(admin.ModelAdmin):
    exclude = ['age']
    form = PersonForm
Glyn Jackson
  • 8,228
  • 4
  • 29
  • 52
  • You can also override the form template:https://docs.djangoproject.com/en/dev/ref/contrib/admin/#custom-template-options – Glyn Jackson Feb 04 '13 at 17:03
  • How do I override it just for add, not for change. – Gordon Wrigley Feb 04 '13 at 17:04
  • Actually I can do that with get_form, but that's only a small part of the problem. – Gordon Wrigley Feb 04 '13 at 17:05
  • you mean overriding the save method? – Glyn Jackson Feb 04 '13 at 17:15
  • once you have created your custom form and added it to the admin you can just add def save function to the from i.e. def save(self, force_insert=False, force_update=False). For example: http://stackoverflow.com/questions/817284/overriding-the-save-method-in-django-modelform – Glyn Jackson Feb 04 '13 at 17:17
  • I need a different set of fields and inlines for the add page compared to the change page. The add page will serve to initially establish a few core relations that will be readonly on the change page were a lot of additional information is available for modification. The change page currently has 18 fields, the add page needs 3, one of which isn't even on the change page and the other 2 are readonly on the change page. – Gordon Wrigley Feb 04 '13 at 17:28
0

So what worked in the end was to create a regular form (not a modelform) with the particular fields I want explicitly instantiated.

Then I copied ModelAdmin.add_view from django.contrib.admin.options into my ModelAdmin, I then hacked around with the copy extensively, half the code in there is for inlines, so that went and half of the rest is around saving which I also didn't need.

In the remaining bits you want to look for and replace at least the fieldsets, readonly_fields, form and title.

Then finally I used get_urls to redirect the add url to my new view.

The nice thing about this approach is with a little re-factoring it can be used to pop generic input forms anywhere in the admin.

One little Grappelli thing, to get the autocomplete and related lookups going you need to specify autocomplete_lookup_fields and/or related_lookup_fields on some object and pass that object to helpers.AdminForm as model_admin, normally this would be your ModelAdmin, but it doesn't seem to care what the object actually is, so I put them on the Form and passed that.

Gordon Wrigley
  • 11,015
  • 10
  • 48
  • 62