Django中跨模型引用字段计算价格,如何隐藏关联字段?
解决Django跨模型引用字段且不在Admin显示的方案
方案1:在Admin中隐藏已有的OneToOneField
如果不想改动现有模型结构,最简单的方式是在Admin配置里把关联字段排除显示:
# admin.py from django.contrib import admin from .models import Offer class OfferAdmin(admin.ModelAdmin): # 方式1:指定要显示的字段,不包含关联字段 fields = ['price', '其他需要显示的字段'] # 方式2:直接排除关联字段 # exclude = ['actual'] admin.site.register(Offer, OfferAdmin)
这样既保留了模型间的关联用于计算price,又不会在Admin界面看到这个字段。
方案2:使用模型属性(Property)动态查询关联数据
如果不想在Offer模型中保留外键字段,可以通过模型属性动态查询Actual的mrrp。前提是两个模型之间有可关联的唯一标识(比如商品sku):
# models.py from django.db import models class Actual(models.Model): sku = models.CharField(max_length=50, unique=True) mrrp = models.DecimalField(max_digits=10, decimal_places=2) # 其他字段... class Offer(models.Model): sku = models.CharField(max_length=50) # 无需外键字段 @property def price(self): # 根据sku匹配Actual记录,编写价格计算逻辑 try: actual = Actual.objects.get(sku=self.sku) return actual.mrrp * 0.9 # 示例:按mrrp打9折 except Actual.DoesNotExist: return None # 处理无匹配记录的情况
注意:这种方式每次访问price都会触发数据库查询,适合数据量不大的场景。
方案3:使用信号(Signal)同步计算价格
如果希望price字段存储在数据库中而非动态计算,可以用Django信号监听Actual的变化,自动更新对应Offer的price:
# models.py from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver class Actual(models.Model): sku = models.CharField(max_length=50, unique=True) mrrp = models.DecimalField(max_digits=10, decimal_places=2) class Offer(models.Model): sku = models.CharField(max_length=50) price = models.DecimalField(max_digits=10, decimal_places=2, null=True) # 信号接收器:Actual保存后自动更新对应Offer的价格 @receiver(post_save, sender=Actual) def update_offer_price(sender, instance, **kwargs): offers = Offer.objects.filter(sku=instance.sku) for offer in offers: offer.price = instance.mrrp * 0.9 # 自定义计算逻辑 offer.save()
这种方式price字段存在数据库中,查询时无需额外关联,但要注意数据同步的一致性(比如删除Actual时需同步处理Offer)。
内容的提问来源于stack exchange,提问作者Mr Layman
相关产品推荐
相关产品推荐

