【问题标题】:Django Admin with custom form; calculate field not in form带有自定义表单的 Django Admin;计算字段不在表单中
【发布时间】:2021-10-13 01:41:09
【问题描述】:

在正常(无管理员视图)中,如果有一个由后端计算的字段,而不是在表单中,则可以这样处理:

obj = form.save(commit=False)
obj.calc_me = calc_at_now()
obj.save

现在说我有一个 Foo 的管理模型

@admin.register(Foo)
class FooAdmin(admin.ModelAdmin):
    exclude = ['calc_me']

我如何告诉 Django 在保存Foo 时,用obj.calc_me = calc_at_now() 计算必填字段?

BaseModelAdmin我看到有一个方法:

    def save_model(self, request, obj, form, change):
        """
        Given a model instance save it to the database.
        """
        obj.save()

因为它没有记录,重写这个函数是不是有点hacky?

或者重写模型的清理方法怎么样?

class Foo(models.Model):
    def clean(self):        
        self.calc_me = calc_at_now()
        super().clean()

推荐的方法是什么。尝试以正确的方式开始使用表单。

【问题讨论】:

    标签: django django-forms django-admin


    【解决方案1】:

    我建议改用 pre_save 或 post_save 信号,除非您的方案仅适用于管理页面。

    https://docs.djangoproject.com/en/3.2/topics/signals/

    【讨论】:

    • 感谢您的推荐。当我真的处于泡菜中时,我尝试只使用信号。我的研究表明,信号有时可能是一种反模式。
    • 在这种情况下,您可以按照上面的建议覆盖模型上的保存方法
    【解决方案2】:

    您可以通过在模型中添加保存方法来做到这一点 喜欢

    class Foo(models.Model):
        ....
        ....
        def save(self, *args, **kwargs):
            self.calc_me = calc_at_now()
            super(Collector, self).save(*args, **kwargs)
    

    让我们试一试

    【讨论】:

      【解决方案3】:

      您可以在管理类中覆盖 save_model() 并保存任何模型字段。

      @admin.register(Foo)
      class FooAdmin(admin.ModelAdmin):
          ...
      
          def save_model(self, request, obj, form, change):
      
              # save any field value
              obj.calc_me = calc_at_now()
      
              super().save_model(request, obj, form, change)
      

      您还可以在 save_model() 中使用 change 标志来区分添加表单和更改表单。

      【讨论】:

        猜你喜欢
        • 2011-06-15
        • 2015-01-13
        • 2014-12-20
        • 2011-03-29
        • 1970-01-01
        • 2014-01-12
        • 2017-12-17
        • 1970-01-01
        相关资源
        最近更新 更多