Override the save_model method

I have a problem and solved with:

class HistoryAdmin(admin.ModelAdmin):
(return model :History)

def get_queryset(self, request, *args, **kwargs):

    return JigLedger.objects.all()  

  (# return  model : JigLedger)

def save_model(self, request, obj, form, change):
# JigLedger ×
# History √
(save model: History)

super(HistoryAdmin, self).save_model(request, obj, form, change)
( The current obj is JigLedger )


I Using the save_model method in admin.ModelAdmin, where obj is the model instance, returns a new model instance jigLdeger because get_queryset is used, but I want to override save_model to implement the save function, I want to change the save_model parameter obj to model instance history. How to solve this problem? thank you

Side note - you need to use the backtick character - `, not “smart quotes” or apostrophes - '.

Please provide the complete HistoryAdmin class here.

Also, what do you mean that you want to “change the save_model parameter obj to model instance history”? You can use whatever name you want as the positional parameters, as long as you’re consistent within the method. (However, I recommend against doing so. There’s a lot to be said for keeping the standard Django naming conventions as much as possible.)


class History(BaseModel):

    Sn = models.ForeignKey('Jig', verbose_name='编码', on_delete=models.CASCADE)
    Rule = models.ForeignKey('Rule', verbose_name='规则',on_delete=models.CASCADE)
    Result_choice = ((None, '请选择 '), (0, '已保养'), (1, '未保养'))
    Result = models.IntegerField(default=1, choices=Result_choice, verbose_name='结果')
    MaintainTime = models.DateTimeField(verbose_name='时间') 

class JigLedger(BaseModel):

    Sn = models.ForeignKey('Jig', verbose_name='编码', on_delete=models.CASCADE)  
    Choice = (
        (None, '请选择'), (0, '正常使用'), (1, '保养预警'), (2, '保养过期'), (3, '维修中'), (4, '报废'), (5, '封存'))
    Status = models.IntegerField(default=0, choices=Choice, verbose_name='状态')
    Manager = models.ForeignKey(User, verbose_name='管理', on_delete=models.CASCADE)
    creator = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='creator', on_delete=models.PROTECT,
    history = HistoricalRecords()
class HistoryAdmin(admin.ModelAdmin):

    list_display = ('Sn', 'status', 'Manager', 'creator', 'default_status', 'create_time', 'last_update_time',)

    def get_queryset(self, request, *args, **kwargs):

        return JigLedger.objects.all()

    def status(self, obj):
        if obj.Status == 1:
            return u'%s' % '保养预警'
        elif obj.Status == 0:
            return u'%s' % '正常使用'
        elif obj.Status == 2:
            return u'%s' % '保养过期'
        elif obj.Status == 3:
            return u'%s' % '维修中'
        elif obj.Status == 4:
            return u'%s' % '报废'
            return u'%s' % '封存'

    status.short_description = '状态'

    def Manager(self, obj):
        return obj.Manage

    Manager.short_description = '管理'

    def creator(self, obj):
        return obj.creator

    creator.short_description = '操作人员'

    def create_time(self, obj):
        return obj.create_time

    creator.short_description = '创建时间'

    def last_update_time(self, obj):
        return obj.last_update_time

    def has_add_permission(self, request):
        # 禁用添加按钮
        return False

    def has_delete_permission(self, request, obj=None):
        # 禁用删除按钮
        return False

    # 操作的是JigLedger
    def default_status(self, obj):
        if obj.Status == 1 or obj.Status == 2:
            return format_html(
                '<span style="color: red;">{}</span>',
            return format_html(
                '<span style="color: green;">{}</span>',

    default_status.short_description = '维保状态'

    def save_model(self, request, obj, form, change):
		Sn = request.POST.get('Sn')
        Rule = request.POST.get('Rule')
        Result = request.POST.get('Result')
        MaintainTime = request.POST.get('MaintainTime')
	  目前的obj 是JigLedger,而不是History
        super(HistoryAdmin, self).save_model(request, obj, form, change)

admin.site.register(History, HistoryAdmin)


Ok, so what is it that you’re asking about here?

There are a couple things I’ve noticed:

You shouldn’t be doing any of this.

The obj that you’re being passed is the object created from the form.

Review the docs for save_model.

Also, you’ve registered this as an admin page for the History model. However, your get_queryset is returning a queryset for JigLedger, which is not correct. See the docs for get_queryset.

In fact, the function I want to implement is to query all the information in JIGLEDGER in HistoryAdmin. After using list_display display, and then operate, so that the Save_model method is saved in the History table.

    def save_model(self, request, obj, form, change):
      super().save_model(request, obj, form, change)

      #	'JigLedger' object has no attribute 'Result_choice'
        super(HistoryAdmin, self).save_model(request, obj, form, change)

This is not the purpose or function for the Django admin - unless I’m still not understanding what you’re trying to do here.

Can you explain this in a little more detail? I’m not following what you mean by this.

If you’re editing or adding data to History, then the queryset for the list view is for History.

If you want to create data in History based on data in JigLedger, then you should create a view to do that.

You could create a ModelAdmin class based on JigLedger to save to History, but that’s really not a good idea.

I suggest you read the first two paragraphs at The Django admin site | Django documentation | Django


def get_queryset(self, request, *args, **kwargs):

       return JigLedger.objects.filter(Q(Status=2) | Q(Status=1))




(希望 translate.google.com 对我的回复同样出色。)

然后,您想为“JigLedger”创建 ModelAdmin 类——这些是您正在选择和编辑的对象。

完成这些对象的编辑后,是的,您可以将代码添加到 save_model 方法以创建 History 的实例并保存它_除了_保存修改后的 JigLedger 实例。

这应该 History 的 ModelAdmin 类。

— The original English —

This description helps a lot, thanks.

(Hopefully translate.google.com does as good a job on my reply.)

You want to then create your ModelAdmin class for JigLedger - those are the objects that you are selecting and editing.

After you are finished editing those objects, then yes, you can add code to the save_model method to create an instance of History and save it in addition to saving the modified instance of JigLedger.

This should not be a ModelAdmin class for History.


class HistoryAdmin(admin.ModelAdmin):


def get_queryset(self, request, *args, **kwargs):

      return JigLedger.objects.all()


def save_model(self, request, obj, form, change):

      super().save_model(request, obj, form, change)

      #	'JigLedger' object has no attribute 'Result_choice'
        super(HistoryAdmin, self).save_model(request, obj, form, change)





  • 将其设为 JigLedger 的 ModelAdmin 类,而不是 History

  • 在你的 save_model 方法中,保存修改后的 JigLedger 对象。

  • 然后,使用该数据创建您的 History 对象(可能使用 create 方法)。

现在,关于 print(obj.Result_choice) 的问题,错误消息与所写的完全一致。 您在 JigLedger 中没有名为 Result_choice 的字段。

— The original English —

I know it can be difficult working through the translation.

I’ll try to say this as directly as I can.

What you want to do is:

  • Make this a ModelAdmin class for JigLedger, not History

  • In your save_model method, save the modified JigLedger object.

  • Then, use that data to create your History object (perhaps using the create method).

Now, regarding the issue with print(obj. Result_choice), the error message is exactly as written. You do not have a field named Result_choice in JigLedger.

Thanks! I solved this problem