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

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

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

【问题讨论】:

    标签: django drop-down-menu django-forms country django-widget


    【解决方案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 choicesform 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】:
                    【解决方案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 错误。
                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2010-11-17
                      • 1970-01-01
                      • 2014-12-19
                      • 2014-11-15
                      • 1970-01-01
                      相关资源
                      最近更新 更多