如何使用相同模型的其他字段的值在Django模型中创建一个字段? [英] How to create a field in django model using values of other fields of same model?

查看:254
本文介绍了如何使用相同模型的其他字段的值在Django模型中创建一个字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个字段名称: total ,其中包含所有产品的总价格*数量.我想要的是如何在Django模型中执行total = price*quantity.如您所见,可能有不止一种产品.
我已通过tabularinline将OderItem模型与Order一起加入.

I wants to create a field name:total which have the total price of all the products*quqantity. What I want is how can I do total = price*quantity in django model. As you can see there can be more than one products.
I have join the OderItem model with Order through tabularinline.

class OrderItemInline(admin.TabularInline):
    model = OrderItem
    raw_id_fields = ['product']

class OrderAdmin(admin.ModelAdmin):
    list_display = ['id','name', 'mobile_no','address','status', 'created']
    list_editable = ['status']
    list_per_page = 15
    list_filter = ['status']
    search_fields = ('id',)
    inlines = [OrderItemInline]


admin.site.register(Order, OrderAdmin)

class Order(models.Model):
    name = models.CharField(max_length=60)
    email = models.EmailField(max_length=60,default=None, blank=True)
    mobile_no = models.CharField(max_length=13, default=None) 
    address = models.CharField(max_length=150)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    status_choices = (
        ('In Queue', 'In Queue'),
        ('Processing', 'Processing'),
        ('Ready', 'Ready'),
        ('Delivered', 'Delivered'),
        ('Paid', 'Paid'),
        ('Cancelled', 'Cancelled'),
    ) 
    status = models.CharField(max_length=15,       choices=status_choices, default=status_choices[0][0])


    class Meta:
        ordering = ('created', )

    def __str__(self):
        return 'Order {}'.format(self.id)

    def get_total_cost(self):
        return sum(item.get_cost() for item in self.items.all())



class OrderItem(models.Model):
    order = models.ForeignKey(Order, related_name='items', 
    on_delete=models.CASCADE)
    product = models.ForeignKey(MenuVariant, related_name='order_items', 
    on_delete=models.CASCADE, default=None)
    size = models.CharField(max_length=20, default=None)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    quantity = models.PositiveIntegerField(default=1)
    # total = models.DecimalField(max_digits=10, decimal_places=2,default=0)



    def __str__(self):
        return '{}'.format(self.id)

    def get_cost(self):
        return self.price * self.quantity

推荐答案

虽然我像dirkgroten不太了解将值保存在模型字段中的意义,但您可以在total=models.IntegerField(null=True, blank=True) >建模并使用post_save来更新值.

While I, like dirkgroten don't quite see the point of saving the value in a model field, you could add a field total=models.IntegerField(null=True, blank=True) to your Order model and use a post_save to update the value.

因此,由于您已经拥有get_total_cost(),因此我们可以执行以下操作:

So, since you already have a get_total_cost() we can do something like:

def order_pre_save(sender, instance, **kwargs):
    instance.total_cost = instance.get_total_cost()

pre_save.connect(order_pre_save, sender=Order)

正如dirkgroten指出的那样,您需要在OrderItem上使用post_save:

As dirkgroten points out you'll need the post_save on the OrderItem:

def order_item_pre_save(sender, instance, **kwargs):
    instance.order.total_cost = instance.order.get_total_cost()
    instance.order.save()

post_save.connect(order_item_pre_save, sender=OrderItem)

您还需要在删除时更新值:

And you'd also need to update the value on delete:

def order_item_pre_delete(sender, instance, **kwargs):
    instance.order.total_cost = instance.order.get_total_cost() - instance.get_cost()
    instance.order.save()

post_delete.connect(order_item_pre_delete, sender=OrderItem)

这篇关于如何使用相同模型的其他字段的值在Django模型中创建一个字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆