如何正确地使用Django中的“选择”字段选项

时间:2022-04-24 02:18:05

I'm reading the tutorial here: https://docs.djangoproject.com/en/1.5/ref/models/fields/#choices and i'm trying to create a box where the user can select the month he was born in. What I tried was

我正在阅读本教程:https://docs.djangoproject.com/en/1.5/ref/models/fields/#选项,我正在尝试创建一个框,用户可以在其中选择出生月份。我试着是什么

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

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

Is this correct? I see that in the tutorial I was reading, they for some reason created variables first, like so

这是正确的吗?我在阅读的教程中看到,他们出于某种原因首先创建了变量,就像这样

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

Why did they create those variables? Also, the MONTHS_CHOICES is in a model called People, so would the code I provided create a "Months Choices) column in the database called called "People" and would it say what month the user was born in after he clicks on of the months and submits the form?

他们为什么要创建这些变量?而且,这个月的选择是在一个名为People的模型中,所以我提供的代码会创建一个名为“People”的数据库中的“数月选择”专栏,它会说用户在几个月的点击后出生,然后提交表单吗?

3 个解决方案

#1


16  

According to the documentation:

根据文档:

Field.choices

Field.choices

An iterable (e.g., a list or tuple) consisting itself of iterables of exactly two items (e.g. [(A, B), (A, B) ...]) to use as choices for this field. If this is given, the default form widget will be a select box with these choices instead of the standard text field.

一个可迭代的(例如,一个列表或一个元组),它由恰好两个项目(例如[(a, B), (a, B)…)组成,用来作为这个字段的选择。如果给出了这个选项,默认的表单小部件将是一个带有这些选项的选择框,而不是标准的文本字段。

The first element in each tuple is the actual value to be stored, and the second element is the human-readable name.

每个元组中的第一个元素是要存储的实际值,第二个元素是人类可读的名称。

So, your code is correct, except that you should either define variables JANUARY, FEBRUARY etc. or use calendar module to define MONTH_CHOICES:

所以,您的代码是正确的,除了您应该定义变量JANUARY, feb等或者使用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


51  

I think no one actually has answered to the first question:

我认为没有人真正回答过第一个问题:

Why did they create those variables?

他们为什么要创建这些变量?

Those variables aren't strictly necessary. It's true. You can perfectly do something like this:

这些变量不是绝对必要的。这是真的。你可以这样做:

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

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

Why using variables is better? Error prevention and logic separation.

为什么使用变量更好?错误预防和逻辑分离。

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

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

Now, imagine you have a view where you create a new Model instance. Instead of doing this:

现在,假设您有一个视图,其中您创建了一个新的模型实例。而不是这样做:

new_instance = MyModel(month='JANUARY')

You'll do this:

你会这样做:

new_instance = MyModel(month=MyModel.JAN)

In the first option you are hardcoding the value. If there is a set of values you can input, you should limit those options when coding. Also, if you eventually need to change the code at the Model layer, now you don't need to make any change in the Views layer.

在第一个选项中,您正在对值进行硬编码。如果您可以输入一组值,那么在编写代码时应该限制这些选项。此外,如果您最终需要更改模型层的代码,那么现在不需要对视图层进行任何更改。

#3


3  

You can't have bare words in the code, that's the reason why they created variables (your code will fail with NameError).

代码中不能有裸字,这就是它们创建变量的原因(您的代码将在NameError中失败)。

The code you provided would create a database table named month (plus whatever prefix django adds to that), because that's the name of the CharField.

您提供的代码将创建一个名为month的数据库表(加上前缀django添加的内容),因为这是CharField的名称。

But there are better ways to create the particular choices you want. See a previous Stack Overflow question.

但是有更好的方法来创建你想要的特定选择。请参见先前的堆栈溢出问题。

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

#1


16  

According to the documentation:

根据文档:

Field.choices

Field.choices

An iterable (e.g., a list or tuple) consisting itself of iterables of exactly two items (e.g. [(A, B), (A, B) ...]) to use as choices for this field. If this is given, the default form widget will be a select box with these choices instead of the standard text field.

一个可迭代的(例如,一个列表或一个元组),它由恰好两个项目(例如[(a, B), (a, B)…)组成,用来作为这个字段的选择。如果给出了这个选项,默认的表单小部件将是一个带有这些选项的选择框,而不是标准的文本字段。

The first element in each tuple is the actual value to be stored, and the second element is the human-readable name.

每个元组中的第一个元素是要存储的实际值,第二个元素是人类可读的名称。

So, your code is correct, except that you should either define variables JANUARY, FEBRUARY etc. or use calendar module to define MONTH_CHOICES:

所以,您的代码是正确的,除了您应该定义变量JANUARY, feb等或者使用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


51  

I think no one actually has answered to the first question:

我认为没有人真正回答过第一个问题:

Why did they create those variables?

他们为什么要创建这些变量?

Those variables aren't strictly necessary. It's true. You can perfectly do something like this:

这些变量不是绝对必要的。这是真的。你可以这样做:

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

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

Why using variables is better? Error prevention and logic separation.

为什么使用变量更好?错误预防和逻辑分离。

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

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

Now, imagine you have a view where you create a new Model instance. Instead of doing this:

现在,假设您有一个视图,其中您创建了一个新的模型实例。而不是这样做:

new_instance = MyModel(month='JANUARY')

You'll do this:

你会这样做:

new_instance = MyModel(month=MyModel.JAN)

In the first option you are hardcoding the value. If there is a set of values you can input, you should limit those options when coding. Also, if you eventually need to change the code at the Model layer, now you don't need to make any change in the Views layer.

在第一个选项中,您正在对值进行硬编码。如果您可以输入一组值,那么在编写代码时应该限制这些选项。此外,如果您最终需要更改模型层的代码,那么现在不需要对视图层进行任何更改。

#3


3  

You can't have bare words in the code, that's the reason why they created variables (your code will fail with NameError).

代码中不能有裸字,这就是它们创建变量的原因(您的代码将在NameError中失败)。

The code you provided would create a database table named month (plus whatever prefix django adds to that), because that's the name of the CharField.

您提供的代码将创建一个名为month的数据库表(加上前缀django添加的内容),因为这是CharField的名称。

But there are better ways to create the particular choices you want. See a previous Stack Overflow question.

但是有更好的方法来创建你想要的特定选择。请参见先前的堆栈溢出问题。

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