2011-01-15 2 views
11

Открыть поле;Варианты выбора модели Django - не было бы лучше диктовать?

domain_status_choices = (
    (1,'Live') 
    (2,'Offline') 
    (3,'Dev') 
) 
status = models.SmallIntegerField(choices=domain_status_choices) 

Я знаю, что могу получить и установить числовое представление и использовать get_status_display(), чтобы получить текстовую метку. Но если пользователь отправляет status=Offline, как я могу получить числовое значение, чтобы сохранить его? Я также хотел бы иметь возможность проверить, что цифры или текстовые значения указаны в списке.

Для меня имеет смысл использовать dict. Вот мой текущий метод;

domain_status_choices = { 
    1: 'Live', 
    2: 'Offline', 
    3: 'Dev', 
} 
status = models.SmallIntegerField(choices=domain_status_choices.iteritems()) 
... 
if input1 not in domain_status_choices.keys(): print "invalid" 
if input2 not in domain_status_choices.items(): print "invalid" 
status = [k for k, v in domain_status_choices.iteritems() if v == input3][0] 

Есть ли лучший способ? Почему обычно используется кортеж кортежей?

+0

Вы пробовали использовать collections.OrderedDict для этого случая использования? (Чтобы сохранить порядок опций.) Http://pymotw.com/2/collections/ordereddict.html –

ответ

13

Я считаю, что ключи от дикта не будут сортироваться (если вы не используете OrderedDict). То есть вы «можете» получить версию «Offline», «Dev», «Live» с вашей версией.

Реализация Обратите внимание на dict.items:

Ключи и значения перечислены в произвольном порядке, который не является случайным, различается по реализации Python, и зависит от истории словаря вставок и удалений.

+0

Вот мысль, в моем случае с числовыми клавишами я мог бы использовать список? (не список кортежей) Или, если меня не беспокоит порядок, я мог бы придерживаться этого метода. – Jake

+0

Благодаря тому, как работает Python, вы можете свободно создавать все, что вы передаете «выбору» поля, как хотите. Если вы в основном используете выбор каким-либо другим способом, я не вижу ничего плохого в преобразовании этого списка/dict/what только при передаче его в поле «» (например, если 'iteritems' работает для вас, то хорошо). Дело просто: Django предполагает, что порядок выбора не должен быть произвольным. – vicvicvic

3

Расширение на мой комментарий на ответ @ vicvicvic в:

t = [ 'Live', 'Offline', 'Dev', ] 
status = models.SmallIntegerField(choices=[(i,t[i]) for i in range(len(t))]) 
... 
if not 0 <= int(input1) < len(t): print "invalid" 
if input2 not in t: print "invalid" 
status = t.index(input2) 
+3

Используйте перечисление для pythonicity: '[(i, v) для i, v в перечислении (t)]' – TryPyPy

+4

Как насчет 'just enumerate (t)' – Jake

Смежные вопросы