如何在模型字段中使用布尔选项来启用/禁用其他字段.如果布尔值为true/false,我希望它启用/禁用其他模型字段.有没有办法使用django models/forms/widgets本地表达这些关系?我一直在编写自定义模板来模拟这些关系,但是如果没有特殊模板,就无法找到在django中表示它们的好方法.
例如:
class PointInTime(models.Model): is_absolute_time = models.BooleanField() absolute_time = models.DateTimeField() is_relative_time = models.BooleanField() days_before = models.IntegerField()
因此,如果is_absolute_time为True,我希望在GUI中可以编辑absolute_time条目,并且days_before条目将变为灰色且不可编辑.如果'is_relative_time'标志为True,我希望absolute_time条目显示为灰色,并且days_before值可以编辑.因此,is_absolute_time和is_relative_time将是GUI中同一组中的单选按钮,并且只有在选中单选按钮时,它们的两个相应字段才可编辑.这在定制模板中很容易做到,但是有没有办法在django中使用模型/表单来本地显示这种关系?
通过"本地展示这种关系"澄清你的意思是有帮助的,并清楚地思考关注点的分离.
如果你想要的只是"灰显"或根据另一个字段的值禁用某个字段,这纯粹是一个表示/ UI问题,所以模板(和/或Javascript)是处理它的合适位置.
如果要验证提交的数据是否内部一致(即如果is_absolute_time为True,则填写absolute_time等),这是表单验证问题.该逻辑的位置在Form或ModelForm对象的clean()方法中.
如果您想确保在没有内部一致性的情况下不能将PointInTime模型保存到数据库,那么这就是数据层问题.它的位置在模型对象的自定义save()方法中(Django 1.2将包含更广泛的模型验证系统).
所有这些选项都涉及编写命令式代码,以便根据这些特定字段执行所需操作.可能是您正在寻找一种在模型中以声明方式表示情况的方法,以便上述所有三种情况中的代码都可以一般而不是具体地编写.没有内置的Django方法可以做到这一点,但你当然可以这样做:
class PointInTime(models.Model): field_dependencies = {'is_absolute_time': 'absolute_time', 'is_relative_time': 'days_before'} ... fields here ...
然后你的模型save()代码(或你的Form clean()代码,或你的模板)可以使用这个字典来确定哪些字段应该启用/禁用,具体取决于哪个字段的值.然而,这种推广几乎不值得付出努力,除非你预计需要在许多不同的模型中做同样的事情.
最后,您可能需要考虑一些架构设计替代方案,以使您的数据层更好地规范化:
如果只有两个有效状态(绝对和相对),则使用单个布尔字段而不是两个.然后你避免可能的不一致(如果两个布尔都是假的话,这意味着什么?或者是真的?)
或者通过完全消除布尔值并在absolute_time/days_before中的一个或另一个中使用Null值进一步简化.
如果可能有两个以上的有效状态,请使用带有选项的单个IntegerField或CharField,而不是使用两个布尔字段.与上述相同的原因,但可以容纳两个以上的选项.
由于RelativeTime和AbsoluteTime似乎彼此不共享任何数据字段,因此请考虑将它们完全拆分为单独的模型.如果你有其他模型需要一个ForeignKey到一个或另一个,你可以使用继承模型(RelativeTime和AbsoluteTime都继承自PointInTime,其他模型有ForeignKeys到PointInTime).