Как я могу использовать формы / модели Django для представления выбора между полями? - PullRequest
4 голосов
/ 03 февраля 2009

Как я могу использовать логический выбор в поле модели, чтобы включить / отключить другие поля. Если логическое значение равно true / false, я хочу включить / отключить другие поля модели. Есть ли способ выразить эти отношения с помощью моделей / форм / виджетов django? Я продолжаю писать собственные шаблоны для моделирования этих отношений, но не могу найти хороший способ представить их в 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, я хочу, чтобы запись absolute_time была редактируемой в графическом интерфейсе, а запись days_before - серой и недоступной для редактирования. Если флаг 'is_relative_time' равен True, я хочу, чтобы запись absolute_time была серой, а значение days_before редактируемым. Поэтому is_absolute_time и is_relative_time будут переключателями в одной и той же группе в графическом интерфейсе, и их два соответствующих поля будут доступны для редактирования только при выборе их переключателя. Это легко сделать в настраиваемом шаблоне, но есть ли способ использовать модель / форму в django для естественного отображения этих отношений?

Ответы [ 2 ]

6 голосов
/ 03 февраля 2009

Было бы полезно уточнить, что вы подразумеваете под «естественным образом показать эти отношения», и четко подумать о разделении интересов.

Если все, что вам нужно, это «выделить серым» или отключить определенное поле на основе значения другого поля, это просто проблема представления / пользовательского интерфейса, поэтому шаблон (и / или Javascript) является подходящим местом для обработки это.

Если вы хотите проверить, что представленные данные внутренне непротиворечивы (т.е. абсолютное время заполнено, если 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).

1 голос
/ 03 февраля 2009

Я не совсем уверен, что вы делаете с этими объектами, но какой бы пользователь не выбрал, вы указываете на один момент времени. «5 дней назад» - это «четверг» и наоборот.

То есть, если даты не совпадают с сайтом (например, запись «5 дней назад» по-прежнему будет означать четверг, завтра и т. Д.), Конечно, это только проблема интерфейса? Если это так, я бы использовал единственное значение для даты в вашей модели и позволил бы форме и представлению выполнить всю работу.

Это решает автоматически сгенерированную сторону администратора, так как у вас будет только одно поле, с которым нужно бороться, но оно не даст вам выбора между ними, если вы не напишите свой собственный виджет формы и не переопределите класс ModelAdmin для ваша модель.

Если это не так, игнорируйте этот ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...