24

我有一个地址信息表格。其中一个字段用于地址国家/地区。目前这只是一个文本框。我想要一个下拉列表(ISO 3166 国家)。我是 django 新手,所以我什至还没有使用 Django Select 小部件。有什么好方法可以做到这一点?

将文件中的选项硬编码到某处?将它们放入数据库中?在模板中?

4

16 回答 16

34

查看 CharField 的“选择”参数。

您可能还想看看django-countries

于 2010-06-03T07:37:42.540 回答
23

姜戈国家

from django_countries.fields import CountryField

class Foo(models.Model):
    country = CountryField()
于 2010-09-13T12:18:33.350 回答
10

最后使用下面的代码片段,它基本上定义了一个由两个字符国家代码组成的元组。此外,它定义了一个名为 CountryField 的自定义字段类型,并将选择参数默认为上述定义的元组。这会自动呈现为下拉列表。

http://djangosnippets.org/snippets/494/

于 2010-06-04T05:27:03.903 回答
8

姜戈国家

from django_countries.countries import COUNTRIES

class CountryForm(forms.Form):
      country= forms.ChoiceField(COUNTRIES)
于 2010-08-28T21:54:37.903 回答
5

两个低维护项目:

http://code.google.com/p/django-countries/

https://github.com/strange/django-country-utils

两个片段:

http://djangosnippets.org/snippets/494/

http://djangosnippets.org/snippets/1476/

现在,我要找一个片段。

于 2011-11-24T15:47:43.967 回答
4

正如之前的答案所述,有一个CountryFieldin django-countries。这是一个模型字段。

如果需要以普通形式(不是模型形式)的表单字段,在django-countriesv3.x(肯定在 3.3 中测试)中可以使用以下内容:

from django_countries.data import COUNTRIES

class MyForm(forms.Form):
    country = forms.ChoiceField(sorted(COUNTRIES.items()))
于 2015-05-17T22:22:59.980 回答
3

这是一个带有国家(不仅是)的不错的图书馆:pycountry

与其他解决方案中的硬编码国家相比,它的主要优点是它是 Debian 软件包 pkg-isocodes 的包装器(因此可以自动更新)。它也有翻译。

因此,如果出现新国家或现有国家将合并在一起,您无需更改代码。

我发现使用这个库并使用模型 Country 创建一个简单的 Django 应用程序很有用,例如

然后,您可以通过自定义 django-admin 命令填充并保持最新的“国家”表,如下所述:编写自定义 django-admin 命令

于 2014-01-20T21:45:06.413 回答
2

Django 使用pytz(参见例如django.utils.timezone),并pytz公开一个country_names基于 ISO 3166 的字典(参见 pytz 文档)。

pytz.country_names字典可用于设置模型字段选择表单字段选择

这可能不会涵盖所有边缘情况,但至少它不会向您的 Django 项目添加另一个模糊的外部依赖项。

模型字段的示例(import pytz第一个):

country = models.CharField(max_length=2, choices=pytz.country_names.items())

请注意,dict 键(国家代码)都是大写字母。

要记住的另一件事,以防pytz更新:如 Django模型字段参考中所述

每次choices更改顺序时都会创建一个新迁移。

于 2020-06-19T13:58:25.687 回答
1

将它们放入数据库是一种更好的方法。便于管理。

于 2012-01-24T09:46:07.817 回答
1

我通过使用解决了它multiple=True

from django_countries.fields import CountryField    

class UserProfile(models.Model):
    countries = CountryField(multiple=True)

您可以在文档中阅读更多相关信息:

https://github.com/SmileyChris/django-countries

于 2018-08-20T20:29:21.843 回答
1

链接到包:django-countries
如果在表格中寻找如何做到这一点:

$ pip install django-countries

>>> from django_countries.data import COUNTRIES

>>> Country = forms.ChoiceField(choices = sorted(COUNTRIES.items()))
于 2019-01-24T01:52:46.707 回答
0

这是解决方案:

from django_countries.fields import CountryField

class Foo(TimeStampedModel):

    country = CountryField()
于 2014-09-26T23:16:49.603 回答
0

SmileyChris 似乎很忙且无法使用,因为存储库自 9 月以来一直没有更新。值得庆幸的是,有一个可以分叉的存储库,它与 Django 3 及更高版本兼容。这可以在这里找到:

https://github.com/yunojuno/django-countries/tree/django-30

它通过了拉取请求的所有检查,但是 SmileyChris 没有响应合并请求。

要安装它,只需运行pip install git+https://github.com/yunojuno/django-countries.git

于 2020-01-06T06:13:02.757 回答
0

如果您正在扩展 forms.Form 类,那么您必须在 Countryfield 之后指定 .formfield ,然后在 formfield() 参数中指定您的属性。

from django_countries.fields import CountryField
class CheckOutForm(forms.Form):
    country = CountryField().formfield()

但是,如果您是从 models.Model 类扩展,那么定义 Coutryfield 就足够了。

from django_countries.fields import CountryField
    class CheckOutForm(models.Model):
        country = CountryField()
于 2020-03-08T06:21:16.123 回答
0

我想,Django 没有尝试使用诸如ChoiceFieldor之类的模型字段CharField并将“选择”作为参数传递,该参数包含国家列表作为在 models.py 外部创建的列表中的元组值,Django 有一个紧凑的库,可以在填充时选择国家表格。

from django-countries.fields import CountryField

class foo(models.Model):
   country = CountryField(blank_label='select country')
   ...
于 2021-08-19T08:24:26.503 回答
0

如果您只想在没有安装django-choices的情况下拥有一个国家 ChoiceField ,您可以创建一个额外的文件,其中包含一个包含来自Wikipedia Iso Country Codes的所有选项的元组:

import csv


# Get the file from: "http://geohack.net/gis/wikipedia-iso-country-codes.csv"
with open("wikipedia-iso-country-codes.csv") as f:
    file = csv.DictReader(f, delimiter=',')
    country_names = [line['English short name lower case'] for line in file]

# Create a tuple with the country names
with open("country_names.py", 'w') as f:
    f.write('COUNTRY_CHOICES = (\n')
    for c in country_names:
        f.write(f'    ("{c}", "{c}"),\n')
    f.write(')')

创建的 country_names.py 文件如下所示:

COUNTRY_CHOICES = (
    ("Afghanistan", "Afghanistan"),
    ("Åland Islands", "Åland Islands"),
    ("Albania", "Albania"),
    ("Algeria", "Algeria"),
    ("American Samoa", "American Samoa"),
    ...
)

然后,您可以像这样在表单中使用 COUNTRY_CHOICES:

from django import forms
from country_names import COUNTRY_CHOICES


class CountryForm(forms.Form):
    country= forms.ChoiceField(choices=COUNTRY_CHOICES)
于 2021-10-05T12:58:15.590 回答