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,
                                verbose_name='操作人员')
    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' % '报废'
        else:
            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>',
                'NG'
            )
        else:
            return format_html(
                '<span style="color: green;">{}</span>',
                'OK'
            )

    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')
		
		```
		想实现的功能是
		History.objects.create(Sn=Sn,Rule=Rule,Result=Result,MaintainTime=MaintainTime)
		```
		
   
      ```
	  目前的obj 是JigLedger,而不是History
	  ```
        super(HistoryAdmin, self).save_model(request, obj, form, change)


admin.site.register(History, HistoryAdmin)

thanks!

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)

       print(obj.Result_choice)
      #	'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

实际的想法就是,在一个modeladmin中查询出满足操作的数据,例如维保过期的数据,然后进行维保,维保完成后进行数据的保存在History中。所以使用了

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

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

获取需要操作(维保)的数据。

然后对于操作的操作,就会默认使用save_model的方法对数据保存在History数据库。不知道描述的是否清晰,谢谢

这个描述很有帮助,谢谢。

(希望 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.

thanks,目前的话,我是创建了一个

class HistoryAdmin(admin.ModelAdmin):

在HistoryAdmin中通过get_queryset获取JigLedger需要的数据,

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

      return JigLedger.objects.all()

在通过一些方法获取到了JigLedger中的数据,使用display进行显示,
目前遇到的问题是使用save_model数据库无数据,
发现是是如下打印效果和报错

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

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

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

也就是目前save_model的obj参数应该是History就是ok的,而不是JigLedger,我的理解是否合适?如果我想把obj改为自己想要保存的模型对象,我应该怎么实现,才能实现这样的需求,thanks!

我知道通过翻译工作可能很困难。

我会尽可能直接地说出来。

你想要做的是:

  • 将其设为 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