different fields for add and change pages in admin

前端 未结 9 740
日久生厌
日久生厌 2020-12-05 00:37

I have a django app with the following class in my admin.py:

class SoftwareVersionAdmin(ModelAdmin):
    fields = (\"product\", \"version_number\", \"descrip         


        
相关标签:
9条回答
  • 2020-12-05 00:47

    Using formsets in Django 1.6 I ended up with the following:

    def get_formsets(self, request, obj=None):
        if obj is None:
            # It's a new object
            for field, fieldset in {'hide_me_from_the_first_fieldset': 0,
                                    'me_from_the_second': 1,
                                    'and_me_too': 1}.items():
                self.fieldsets[fieldset][1]['fields'].remove(field)
    
        return super().get_formsets(request, obj)
    

    EDIT: Perhaps a more intuitive way is to specify a separate add_fieldsets property and do:

    def get_formsets(self, request, obj=None):
        if obj is None:
            self.fieldsets = self.add_fieldsets
    
        return super().get_formsets(request, obj)
    
    0 讨论(0)
  • 2020-12-05 00:48

    This specific code did not work for me. I simply change it a little:

    if obj: # obj is not None, so this is a change page
            #kwargs['exclude'] = ['owner']
            self.fields = ['id', 'family_name', 'status', 'owner']
        else: # obj is None, so this is an add page
            #kwargs['fields'] = ['id', 'family_name', 'status']
            self.fields = ['id', 'family_name', 'status']
        return super(YourAdmin, self).get_form(request, obj, **kwargs)
    
    0 讨论(0)
  • 2020-12-05 00:48

    An easy way is to use fieldsets for the Change Page and add_fieldsets for the Add Page.

    0 讨论(0)
  • 2020-12-05 00:53

    dpawlows' solution above is the clearest, I think.

    However, I encountered an additional issue in that type of structure.

    If change_view() makes changes to the model, e.g. specifies readonly_fields that have been filled in in add_view(), these changes persist in add_view() after change_view() has been called. For example:

    def add_view(self, request, extra_context=None):
        return super().add_view(request)
    
    def change_view(self, request, object_id, extra_context=None):
        self.readonly_fields = ['name']  # this change persists in add_view()
        return super().change_view(self, request, object_id)
    

    In this case, after change_view() has been called on any instance, invoking add_view() will show readonly_fields ("name", in this case) set by change_view() and thus protect these fields from filling in.

    This can be solved by adding a 'roll back' assignment in add_view():

    def add_view(self, request, extra_context=None):
        self.readonly_fields = []  # 'roll back' for changes made by change_view()
        return super().add_view(request)
    
    0 讨论(0)
  • 2020-12-05 00:58

    I don't think it's a good idea to override fields or exclude or form, because they are config attributes, so they would not initialize for every request.
    I think the accepted answer by shanyu is a good solution.

    Or we can use the method from UserAdmin:

    def get_fieldsets(self, request, obj=None):                                  
        if not obj:                                                                                                 
            return self.add_fieldsets                                            
        return super(UserAdmin, self).get_fieldsets(request, obj)  
    

    Remember to assign the add_fieldsets yourself. Unfortunately it doesn't fit my use case.

    For Django 1.7. I don't know how they are implemented in other versions.

    0 讨论(0)
  • 2020-12-05 01:06

    This is an old question but I wanted to add that the add_view and change_view methods can be modified for this purpose:

    class SoftwareVersionAdmin(ModelAdmin):
         ...
         def add_view(self,request,extra_content=None):
             self.exclude = ('product','version_number',)
             return super(SoftwareVersionAdmin,self).add_view(request)
    
         def change_view(self,request,object_id,extra_content=None):
             self.exclude = ('product','description',)
             return super(SoftwareVersionAdmin,self).change_view(request,object_id)
    
    0 讨论(0)
提交回复
热议问题