【问题标题】:Calculated field is not getting saved in database in django admin models计算字段未保存在 django 管理模型的数据库中
【发布时间】:2020-10-12 04:17:00
【问题描述】:

我在total_amount() 方法中重新计算了字段total_amount。这在 django admin 中工作正常,但 total_amount 的更新值未保存在数据库列中。

这是我的models.py

class Orders(models.Model):
    order_id = models.IntegerField(primary_key=True)
    order_item = models.ForeignKey('Product', models.DO_NOTHING, db_column='order_item', blank=True, null=True,
        related_name='ordered_item')
    order_status = models.CharField(max_length=100, blank=True, null=True)
    delivery_address = models.TextField(blank=True, null=True)
    customer = models.ForeignKey('User', models.DO_NOTHING, db_column='customer', blank=True, null=True)
    quantity = models.IntegerField()
    rate = models.ForeignKey('Product', models.DO_NOTHING, db_column='rate', blank=True, null=True)
    total_amount = models.DecimalField(blank=True, null=True,decimal_places=2,max_digits=10)

    def total_amount(self):
        rate = Product.objects.get(pk=self.order_item.product_id)
        self.total_amount = rate.price * self.quantity
        return self.total_amount    

    class Meta:
        managed = False
        db_table = 'orders'

我从total_amount() 方法得到的值没有在数据库中更新。

这是我的 admin.py

class OrderAdmin(admin.ModelAdmin):

    list_display = ('order_id', 'order_item', 'order_status', 'delivery_address', 'customer',
        'quantity','unit_rate','total_amount')

    exclude = ['rate']

    readonly_fields = ('unit_rate','total_amount',)
    def unit_rate(self,obj):
        rate = Product.objects.get(pk=obj.order_item.product_id)
        return rate.price

admin.site.register(Orders,OrderAdmin)

【问题讨论】:

  • 该字段不会自动保存。我认为你应该重写 save 方法。

标签: python django django-models django-rest-framework django-admin


【解决方案1】:

正如@minglyu在他的回答中提到的,如果你可以计算total_amount,你不应该将它保存为数据库字段,因为它会引入数据重复。

要回答这个问题 - 如何保存 - 您需要像这样覆盖模型的保存方法:

class Orders(models.Model):
    order_id = models.IntegerField(primary_key=True)
    order_item = models.ForeignKey('Product', models.DO_NOTHING, db_column='order_item', blank=True, null=True,
        related_name='ordered_item')
    order_status = models.CharField(max_length=100, blank=True, null=True)
    delivery_address = models.TextField(blank=True, null=True)
    customer = models.ForeignKey('User', models.DO_NOTHING, db_column='customer', blank=True, null=True)
    quantity = models.IntegerField()
    rate = models.ForeignKey('Product', models.DO_NOTHING, db_column='rate', blank=True, null=True)
    total_amount = models.DecimalField(blank=True, null=True,decimal_places=2,max_digits=10)

    def save(self, *args, **kwargs):
        rate = Product.objects.get(pk=self.order_item.product_id)
        self.total_amount = rate.price * self.quantity
        super(Orders, self).save(*args, **kwargs)

【讨论】:

  • Exception Value: can't set attribute
  • 你注释掉了total_amount字段吗?
  • 是的,它显示Exception Value:super(type, obj): obj must be an instance or subtype of type
  • 这是我的错字。我错误地将Product 而不是Orders 放在最后一行。我已经编辑过了。你现在可以检查吗?
  • 现在错误消失了,但仍然没有在数据库中更新。
【解决方案2】:

你不需要total_amount作为模型字段,因为它可以从其他字段派生,而且最好将total_amount定义为property而不是方法。

# models.py
class Orders(models.Model):
    order_id = models.IntegerField(primary_key=True)
    ...
    # total_amount = models.DecimalField(blank=True, null=True,decimal_places=2,max_digits=10)
   
    @property
    def total_amount(self):
        ...

# admin.py
list_display = (..., 'total_amount')

【讨论】:

  • 还是不行!现在它显示错误Exception Value: can't set attribute
  • @BadDub 你迁移了吗?
  • 删除self,它将起作用。 total_amount = rate.price * self.quantity; return total_amount
  • 是的,我删除了self,错误消失了,但仍然没有保存到数据库中
  • @BadDub 是的,正如我之前提到的,可以动态计算值,而不是保存到数据库。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-17
  • 2021-10-12
  • 2020-07-11
  • 1970-01-01
  • 2017-05-06
  • 2016-11-19
  • 1970-01-01
相关资源
最近更新 更多