Django 根据其他字段动态设置字段值
Posted
技术标签:
【中文标题】Django 根据其他字段动态设置字段值【英文标题】:Django set field values dynamically based on other fields 【发布时间】:2012-06-27 22:50:27 【问题描述】:我正在尝试根据其他外来字段选择设置字段默认值。 基本上,这些是类:
class Product(models.Model):
description = models.CharField('Description', max_length=200)
price = models.FloatField('Price')
class Sell(models.Model):
product = models.ForeignKey(Product)
price = models.FloatField('Price')
每个“产品”都有一个默认价格(或建议价格),因此当用户在管理页面中想要添加新的 Sell 并选择产品时,我需要从 Product.price 动态复制到Sell.price 建议的价格。 我不能使用“保存”方法,因为用户可以在那一刻改变。
是否需要显式使用 javascript?或者 Django 中有没有一种优雅的方式来做到这一点?
【问题讨论】:
【参考方案1】:您可以使用预保存挂钩或覆盖 Sell 模型的 save() 方法来解决此问题。
from django.db import models
class Product(models.Model):
description = models.CharField('Description', max_length=200)
price = models.FloatField('Price')
class Sell(models.Model):
product = models.ForeignKey(Product)
price = models.FloatField('Price')
# One way to do it:
from django.db.models.signals import post_save
def default_subject(sender, instance, using):
instance.price = instance.product.price
pre_save.connect(default_subject, sender=Sell)
# Another way to do it:
def save(self, *args, **kwargs):
self.price = self.product.price
super(Sell, self).save(*args, **kwargs)
【讨论】:
另外一种方法是在模型的clean()
方法中初始化price
字段。很像覆盖save()
,但由于不必调用super()
而更干净,它是专门为此设计的框架钩子:)【参考方案2】:
您是在询问动态更新管理网页中的表单字段值吗?客户端表单行为需要在 JavaScript 中发生。 Django 的 Admin 确实提供了一些脚本,特别是用于添加/删除内联,但它不提供此级别的功能。
Django 的管理员确实在window.django.jQuery
(或只是django.jQuery
)下的页面上下文中提供了jQuery。 Django Forms 始终输出稳定的表单字段 ID。检查输出表单代码并找到 Product 选择器和相应的 Sell.price 输入字段。然后,您可以使用 jQuery 执行一些操作,例如将 .change() 或 .on('change', ...) 处理程序添加到 Product 选择器,并使用更新 Sell 字段中价格的函数。
为了将来参考,Django Admin 几乎可以用ModelAdmin.prepopulated_fields 满足您的要求,但是
prepopulated_fields 不接受 DateTimeField、ForeignKey 或 ManyToManyField 字段。
【讨论】:
以上是关于Django 根据其他字段动态设置字段值的主要内容,如果未能解决你的问题,请参考以下文章
使用 Django,如何在模板中动态设置 ModelForm 字段值?