How to display a custom field only in change view (admin)

django, django-admin

Solution

You're right, it won't work this way, because 'message' is not a field found on the Page model and the ModelAdmin class will ignore the exclusion. You can achieve this in many ways, but I think the best way to do it is this:

class PageAdmin(admin.ModelAmin):
    change_form = PageAdminForm

    ...

    def get_form(self, request, obj=None, **kwargs):
       if obj is not None:
          kwargs['form'] = self.change_form

       return super(UserAdmin, self).get_form(request, obj, **defaults)

Basicaly here django will use an auto-generated ModelForm when adding a Page and your custom form when editing the Page. Django itself uses a similar technique to display different forms when adding and changing a User:

https://github.com/django/django/blob/stable/1.6.x/django/contrib/auth/admin.py (the interesting part is in line 68)

Problem

I'm totally new in Python and Django :) and i need some help. What i want to do: I have a model Page and i need to add a custom field "message" when someone try to update one object. Why? Because i'm building a revision system. This field, it's just an explanation about the change. So this field is not linked to the Page (but to another model PageRevision) After some research i managed to add this field to my form in the admin.py file, like this: ``` class PageAdminForm(forms.ModelForm): # custom field not backed by database message = forms.CharField(required=False) class Meta: model = Page ``` it's working, my field is now displayed...But i don't want this field everywhere. Just when someone try to update a Page object. i have found this answer different-fields-for-add-and-change-pages-in-admin but it's not working for me because it's a custom field (i think). The rest of my code in admin.py: ``` class PageAdmin(admin.ModelAdmin): form = PageAdminForm fields = ["title", "weight", "description", "message"] list_display = ["title", "weight", "description"] list_filter = ["updated_at"] def get_form(self, request, obj=None, **kwargs): if obj is None: # not working ? kwargs['exclude'] = ['message'] # else: # kwargs['exclude'] = ['message'] return super(PageAdmin, self).get_form(request, obj, **kwargs) def save_model(self, request, obj, form, change): if not obj.id: obj.author = request.user obj.modified_by = request.user wiki_page = obj.save() # save page in revision table revision = PageRevision(change=change, obj=wiki_page, request=request) # retrieve value in the custom field revision.message = form.cleaned_data['message'] revision.save() ``` def get_form doesn't exclude my custom message field because i think it doesn't know is existence. If i put another field like title, it's works. So how to exclude the custom field from add view ? Thanks :)

Original source

Related problems