Django:国家下拉列表?
我有一张地址信息表格。其中一个字段用于地址国家/地区。目前这只是一个文本框。我想要一个(ISO 3166 国家/地区)的下拉列表。我是 Django 新手,所以我什至还没有使用过 Django Select 小部件。有什么好的方法可以做到这一点?
将选项硬编码到文件中的某处?把它们存入数据库?在模板中?
I have a form for address information. One of the fields is for the address country. Currently this is just a textbox. I would like a drop down list (of ISO 3166 countries) for this. I'm a django newbie so I haven't even used a Django Select widget yet. What is a good way to do this?
Hard-code the choices in a file somewhere? Put them in the database? In the template?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(16)
查看 CharField 的“choices”参数。
您可能还想查看 django-countries。
Check out "choices" parameter of a CharField.
You might also want to take a look at django-countries.
Django 国家
Django Countries
最终使用下面的代码片段,它基本上定义了两个字符国家/地区代码的元组的元组。此外,它定义了一个名为 CountryField 的自定义字段类型,并将选择参数默认为上面定义的元组。这会自动呈现为下拉列表。
http://djangosnippets.org/snippets/494/
Ended up using the below snippet which basically defines a tuple of tuples of two character country codes. Additionally it defines a custom field type called CountryField and defaults the choices parameter to the above defined tuple. This automatically gets rendered as a drop down list.
http://djangosnippets.org/snippets/494/
姜戈国家
Django Countries
两个低维护项目:
http://code.google.com/p/django-countries/< /a>
https://github.com/strange/django-country-utils
两个片段:
http://djangosnippets.org/snippets/494/
http://djangosnippets.org/snippets/1476/
现在,我要获取一个片段。
Two low mantained projects:
http://code.google.com/p/django-countries/
https://github.com/strange/django-country-utils
Two snippets:
http://djangosnippets.org/snippets/494/
http://djangosnippets.org/snippets/1476/
For now, I am going for a snippet.
正如之前的答案所述,
django-countries
中有一个CountryField
。这是一个模型字段。如果需要普通表单(不是模型表单)的表单字段,在 django-countries v3.x 中(在 3.3 中确实经过测试)可以使用以下内容:
As previous answers have stated, there is a
CountryField
indjango-countries
. This is a model field.If a form field is needed in a plain form (not model form), in
django-countries
v3.x (definitely tested in 3.3) the following can be used:更新(Django >=4.0)
在较旧的 Django 版本中使用 pytz.country_names 很方便,如下所述,但 Django >=4.0 使用
zoneinfo
而不是pytz
。详细信息请参见发行说明和< a href="https://pytz-deprecation-shim.readthedocs.io/en/latest/index.html" rel="nofollow noreferrer">此处。不幸的是,zoneinfo 似乎没有提供 pytz.country_names 的等效项(据我所知)。
然而,Python(第一方)中有一个最新的 ISO 3166 国家/地区名称列表
tzdata
包:iso3166.tab请注意,
tzdata
是 已经安装。仅出于说明目的,这里有一个快速&将 iso3166.tab 文件解析为类似于 pytz.country_names 的肮脏方法(Python 3.9+):
注意,对于 Django 的字段选择,直接创建
list
会比创建dict
更容易。原始版本 (Django <4.0)
Django (<4.0) 使用
pytz
(参见例如 django.utils.timezone),并且pytz
公开一个country_names
字典,基于ISO 3166(请参阅 pytz 文档)。这个 pytz.country_names 字典可用于设置您的 模型字段选择,或表单字段选择。
这可能无法涵盖所有边缘情况,但至少,它不会向您的 Django 项目添加另一个模糊的外部依赖项。
模型字段示例(首先
import pytz
):请注意,字典键(国家/地区代码)均为大写。
另一件要记住的事情是,如果
pytz
被更新:如 Django 模型字段参考UPDATE (Django >=4.0)
Using
pytz.country_names
was convenient in older Django versions, as described below, but Django >=4.0 useszoneinfo
instead ofpytz
. Details in the release notes and here.Unfortunately,
zoneinfo
does not appear to offer an equivalent ofpytz.country_names
(as far as I know).There is, however, an up-to-date list of ISO 3166 country names in Python's (first-party)
tzdata
package: iso3166.tabNote that
tzdata
is already installed if you're using Django 4+ on Windows.For illustrative purposes only, here's a quick & dirty way to parse the iso3166.tab file into a
dict
similar topytz.country_names
(Python 3.9+):Note, for Django's field
choices
, it would be easier to create alist
directly, instead of adict
.ORIGINAL (Django <4.0)
Django (<4.0) uses
pytz
(see e.g. django.utils.timezone), andpytz
exposes acountry_names
dictionary, based on ISO 3166 (see pytz docs).This
pytz.country_names
dictionary can be used to set your model field choices, or form field choices.This might not cover all edge cases, but, at least, it does not add another obscure external dependency to your Django project.
Example for a model field (
import pytz
first):Note that the dict keys (country codes) are all capitals.
One other thing to keep in mind, in case
pytz
is updated: as mentioned in the Django Model field reference这是一个很好的库,其中包含国家/地区(不仅如此): pycountry
它的主要内容与其他解决方案中的硬编码国家/地区相比,它的优点是它是 Debian 软件包 pkg-isocodes 的包装器(因此可以使用它自动更新)。它还有翻译。
因此,如果出现新的国家/地区或现有国家/地区将合并在一起,您无需更改代码。
我发现使用这个库并使用模型 Country 创建一个简单的 Django 应用程序很有用,
然后您可以通过自定义 django-admin 命令填充并保持最新的“国家/地区”表,如下所述:编写自定义 django-admin 命令
Here is a nice library with countries (and not only): pycountry
Its main advantage is that it is a wrapper around Debian package pkg-isocodes (thus can updates automatically with it) compared to hard-coded countries in other solutions. It also has translations.
So if new country appears or existing countries will be merged together you do not need to change your code.
I found it useful to use this library and create a simple Django app with model Country for example
Then you can populate and keep up-to-date your 'country' table by means of custom django-admin command as described here: Writing custom django-admin commands
链接到包:django-countries
如果寻找如何以表格形式进行操作:
Link to package : django-countries
If looking for how to do it in forms :
将它们放入数据库是更好的方法。方便管理。
Put them in the database is a better way. Convenient to management.
我通过使用
multiple=True
解决了这个问题:您可以在文档中阅读更多相关信息:
https://github.com/SmileyChris/django-countries
I solved it by using
multiple=True
:You can read more about it in the docs:
https://github.com/SmileyChris/django-countries
如果您只想拥有一个国家/地区 ChoiceField 而不安装 django-choices 您可以创建一个额外的文件,其中包含 Wikipedia Iso 国家/地区代码 中的所有选择的元组:
创建的country_names.py文件看起来像这样:
然后您可以在表单中使用COUNTRY_CHOICES,如下所示:
If you just want to have a country ChoiceField without installing django-choices you can create an extra file which holds a tuple with all choices from the Wikipedia Iso Country Codes:
The created country_names.py file looks something like this:
You can then use COUNTRY_CHOICES in your form like this:
这是解决方案:
Here is the solution:
SmileyChris 似乎很忙而且没空,因为存储库自 9 月份以来就没有更新过。值得庆幸的是,有一个可以分叉的存储库与 Django 3 及更高版本兼容。可以在这里找到:
https://github.com/yunojuno/django- countries/tree/django-30
它通过了拉取请求的所有检查,但是 SmileyChris 尚未响应合并请求。
要安装它,只需运行
pip install git+https://github.com/yunojuno/django-countries.git
SmileyChris seems to be pretty busy and unavailable, as the repository hasn't been updated since September. Thankfully, there is a repository that can be forked that is compatible with Django 3 and higher. This can be found here:
https://github.com/yunojuno/django-countries/tree/django-30
It passes all checks for a pull request, however SmileyChris has not responded to the merge request.
To install it just run
pip install git+https://github.com/yunojuno/django-countries.git
如果您要扩展 forms.Form 类,那么您必须在 Countryfield 之后指定 .formfield ,然后在 formfield() 参数中指定您的属性。
但如果您从 models.Model 类扩展,那么定义 Coutryfield 就足够了。
If you are extending forms.Form class then you have to specify .formfield right after your Countryfield and then specify your attributes in formfield() parameter.
But if you are extending from models.Model class then defining Coutryfield is enough.
我想,不要尝试使用诸如
ChoiceField
或CharField
之类的模型字段,并将“选择”作为参数传递,其中包含国家/地区列表作为在外部创建的列表中的元组值models.py,Django 有一个紧凑的库,可以在填写表单时选择国家/地区。I guess, instead of trying with models fields such as
ChoiceField
orCharField
and passing 'choices' as a parameter which contains list of countries as tuple values inside the list created outside in the models.py, Django has compact library to work with selecting country while filling the form.