Подтвердить что ты не робот

Как правильно использовать параметр "Выбор" в Django

Я читаю учебник здесь: https://docs.djangoproject.com/en/1.5/ref/models/fields/#choices и я пытаюсь создать окно, в котором пользователь может выбрать месяц, в котором он родился. То, что я пробовал, было

 MONTH_CHOICES = (
    (JANUARY, "January"),
    (FEBRUARY, "February"),
    (MARCH, "March"),
    ....
    (DECEMBER, "December"),
)

month = CharField(max_length=9,
                  choices=MONTHS_CHOICES,
                  default=JANUARY)

Это правильно? Я вижу, что в учебнике, которое я читал, они по какой-то причине сначала создали переменные, например

FRESHMAN = 'FR'
SOPHOMORE = 'SO'
JUNIOR = 'JR'
SENIOR = 'SR'

Почему они создали эти переменные? Кроме того, MONTHS_CHOICES находится в модели под названием People, так что код, который я предоставил, создает столбец "Months Choices" в базе данных под названием "People", и он скажет, в каком месяце родился пользователь после того, как он нажимает на эти месяцы и отправляет форму?

4b9b3361

Ответ 1

В соответствии с документацией:

Field.choices

Итерируемый (например, список или кортеж), состоящий из итерации ровно двух элементов (например, [(A, B), (A, B)...]) для использования в качестве выбор для этого поля. Если это дано, виджет формы по умолчанию будет это поле выбора с этими вариантами вместо стандартного текстового поля.

Первый элемент в каждом кортеже - это фактическое значение, которое нужно сохранить, и второй элемент - это читаемое человеком имя.

Итак, ваш код правильный, за исключением того, что вы должны либо определять переменные JANUARY, FEBRUARY и т.д., либо использовать calendar модуль для определения MONTH_CHOICES:

import calendar

...

class MyModel(models.Model):
    ...

    MONTH_CHOICES = [(str(i), calendar.month_name[i]) for i in range(1,13)]

    month = CharField(max_length=9, choices=MONTHS_CHOICES, default='1')

Ответ 2

Я думаю, никто на самом деле не ответил на первый вопрос:

Почему они создали эти переменные?

Эти переменные не являются строго необходимыми. Это правда. Вы можете сделать что-то вроде этого:

MONTH_CHOICES = (
    ("JANUARY", "January"),
    ("FEBRUARY", "February"),
    ("MARCH", "March"),
    # ....
    ("DECEMBER", "December"),
)

month = models.CharField(max_length=9,
                  choices=MONTH_CHOICES,
                  default="JANUARY")

Почему лучше использовать переменные? Предотвращение ошибок и логическое разделение.

JAN = "JANUARY"
FEB = "FEBRUARY"
MAR = "MAR"
# (...)

MONTH_CHOICES = (
    (JAN, "January"),
    (FEB, "February"),
    (MAR, "March"),
    # ....
    (DEC, "December"),
)

Теперь представьте, что у вас есть представление, где вы создаете новый экземпляр модели. Вместо этого:

new_instance = MyModel(month='JANUARY')

Вы сделаете следующее:

new_instance = MyModel(month=MyModel.JAN)

В первом варианте вы жестко кодируете значение. Если есть набор значений, которые вы можете ввести, вы должны ограничить эти параметры при кодировании. Кроме того, если вам необходимо изменить код на уровне модели, теперь вам не нужно вносить изменения в слой Views.

Ответ 3

У вас не может быть голых слов в коде, причина в том, что они создали переменные (ваш код не сработает с NameError).

Код, который вы предоставили, создаст таблицу базы данных с именем month (плюс любой добавочный плюс django), потому что это имя CharField.

Но есть лучшие способы создать нужные вам варианты. См. предыдущий вопрос о переполнении стека.

import calendar
tuple((m, m) for m in calendar.month_name[1:])