Django:国家下拉列表?

Posted

技术标签:

【中文标题】Django:国家下拉列表?【英文标题】:Django: Country drop down list? 【发布时间】:2011-02-27 04:20:51 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

如果您只想拥有一个国家 ChoiceField 而不安装 django-choices,您可以创建一个额外的文件,其中包含一个包含来自 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)

【讨论】:

【参考方案2】:

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

from django-countries.fields import CountryField

class foo(models.Model):
   country = CountryField(blank_label='select country')
   ...

【讨论】:

【参考方案3】:

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

pytz.country_names 字典可用于设置您的model field choices 或form field choices。

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

模型字段示例(import pytz first):

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

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

要记住的另一件事,以防 pytz 更新:如 Django Model field reference 中所述

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

【讨论】:

【参考方案4】:

Django Countries

from django_countries.fields import CountryField

class Foo(models.Model):
    country = CountryField()

【讨论】:

@monokrome 所以你说的是我是对的,你需要做额外的工作来以任何其他格式表示国家名称。 由于某种原因,该导入对我不起作用。我使用from django_countries.fields import CountryField @JohnLehmann 也许它已经改变了,这是 5 岁。已更新。【参考方案5】:

如果您要扩展 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()

【讨论】:

【参考方案6】:

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

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

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

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

【讨论】:

【参考方案7】:

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

$ pip install django-countries

>>> from django_countries.data import COUNTRIES

>>> Country = forms.ChoiceField(choices = sorted(COUNTRIES.items()))

【讨论】:

考虑添加包的链接【参考方案8】:

我用multiple=True解决了这个问题:

from django_countries.fields import CountryField    

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

您可以在文档中了解更多信息:

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

【讨论】:

【参考方案9】:

查看 CharField 的“choices”参数。

您可能还想看看django-countries。

【讨论】:

请注意,这里有两个 django-countries 项目。链接的数据更全面,但似乎没有得到积极维护,因此请注意过时的数据。 现在好像住在github上:github.com/SmileyChris/django-countries @creimers 谢谢!相应更新。 你可以使用 pytz,而不是额外的 django-countries 依赖,它已经包含在 Django 中。参见示例below。【参考方案10】:

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

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

from django_countries.data import COUNTRIES

class MyForm(forms.Form):
    country = forms.ChoiceField(sorted(COUNTRIES.items()))

【讨论】:

这在使用 django-countries 创建表单时很有帮助。谢谢!【参考方案11】:

解决办法如下:

from django_countries.fields import CountryField

class Foo(TimeStampedModel):

    country = CountryField()

【讨论】:

【参考方案12】:

这是一个不错的图书馆,包含国家(不仅如此):pycountry

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

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

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

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

【讨论】:

【参考方案13】:

两个低维护项目:

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

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

两个sn-ps:

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

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

现在,我要去参加一个sn-p。

【讨论】:

【参考方案14】:

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

【讨论】:

【参考方案15】:

Django 国家

from django_countries.countries import COUNTRIES

class CountryForm(forms.Form):
      country= forms.ChoiceField(COUNTRIES)

【讨论】:

django-countries 现在有一个 CountryField 类。 嗨..有一个问题,当呈现此表单时,默认情况下它显示“阿富汗”,当然这是选择集中的第一个国家..但是如果国家字段是不需要?含义,默认显示----或类似 导入位置好像变了,现在是from django_countries import countries 在表单中使用 django_countries 的官方文档。表单:github.com/SmileyChris/django-countries#custom-forms【参考方案16】:

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

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

【讨论】:

django-countries 提供的完全相同。它是一个可重用的组件。 在 djangosn-ps 的评论中有人建议改用这个 sn-p:djangosnippets.org/snippets/1476 它是最新的并修复了 maxlength 错误。

以上是关于Django:国家下拉列表?的主要内容,如果未能解决你的问题,请参考以下文章

当在另一个下拉列表上进行选择时,如何在 Django 的管理员中过滤下拉列表

Select2 + Django:设置首选列表项

Django:如何创建类别字段/下拉菜单?

使用JS动态创建国家下拉列表[重复]

Codeigniter 上的动态相关下拉列表国家和州

通过jQuery根据位置动态重新排列国家下拉列表?