Было бы полезно прояснить, что вы подразумеваете под «изначально показать эту связь», и четко подумать о разделении задач.
Если все, что вам нужно, это «затенить» или отключить определенное поле на основе значения другого поля, это чисто проблема презентации/интерфейса, поэтому шаблон (и/или Javascript) является подходящим местом для его обработки.
Если вы хотите проверить, что отправленные данные внутренне непротиворечивы (т. е. absolute_time заполняется, если is_absolute_time имеет значение True и т. д.), это проблема проверки формы. Место для этой логики находится в методе clean() вашего объекта Form или ModelForm.
Если вы хотите гарантировать, что никакая модель 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() или ваш шаблон) может использовать этот словарь, чтобы определить, какие поля должны быть включены/отключены в зависимости от значения другого. Однако это обобщение вряд ли стоит затраченных усилий, если только вы не предполагаете, что вам придется делать то же самое в ряде различных моделей.
Наконец, несколько альтернатив дизайна схемы, которые вы, возможно, захотите рассмотреть, чтобы лучше нормализовать свой уровень данных:
Если есть только два допустимых состояния (абсолютное и относительное), используйте одно логическое поле вместо двух. Затем вы избегаете возможных несоответствий (что значит, если оба логических значения имеют значение False? Или True?)
Или еще больше упростите, полностью исключив логические значения и просто используя значения Null в одном или другом из absolute_time/days_before.
Если допустимых состояний может быть более двух, используйте один IntegerField или CharField с вариантами выбора вместо двух логических полей. Та же причина, что и выше, но может быть более двух вариантов.
Поскольку RelativeTime и AbsoluteTime не имеют общих полей данных друг с другом, рассмотрите возможность их полного разделения на отдельные модели. Если у вас есть другие модели, которым нужен ForeignKey для одного или другого, вы можете смоделировать это с наследованием (как RelativeTime, так и AbsoluteTime наследуются от PointInTime, другие модели имеют ForeignKeys для PointInTime).
person
Carl Meyer
schedule
03.02.2009