django_address 模块是否提供了一种方法来播种初始国家/地区数据?
Does the django_address module provide a way to seed the initial country data?
我正在使用 Django 2.0、Python 3.7 和 MySql 5. 我最近安装了 django_address 模块。我注意到当我 运行 我的初始迁移基于我的 models.py 文件时...
from django.db import models
from address.models import AddressField
from phonenumber_field.modelfields import PhoneNumberField
class CoopType(models.Model):
name = models.CharField(max_length=200, null=False)
class Meta:
unique_together = ("name",)
class Coop(models.Model):
type = models.ForeignKey(CoopType, on_delete=None)
address = AddressField(on_delete=models.CASCADE)
enabled = models.BooleanField(default=True, null=False)
phone = PhoneNumberField(null=True)
email = models.EmailField(null=True)
web_site = models.TextField()
它创建了一些地址 tables,包括...
mysql> show create table address_country;
+-----------------+---------------------------------------------------+
| Table | Create Table |
+-----------------+---------------------------------------------------+
| address_country | CREATE TABLE `address_country` ( |
| | `id` int(11) NOT NULL AUTO_INCREMENT, |
| | `name` varchar(40) COLLATE utf8_bin NOT NULL, |
| | `code` varchar(2) COLLATE utf8_bin NOT NULL, |
| | PRIMARY KEY (`id`), |
| | UNIQUE KEY `name` (`name`) |
| | ) ENGINE=InnoDB |
| | DEFAULT CHARSET=utf8 COLLATE=utf8_bin |
+-----------------+---------------------------------------------------+
但是,这个table里面没有数据。模块生成的table有没有办法获取种子数据,还是需要自己去挖掘?
如上所述,您需要自己添加实际数据。您需要准备好并一次性上传。如果您只查找国家/地区数据,this is a good source. There is also a django app called django-countries which lets you have a lot more data and controls including flags, ISO codes etc. Another database with 3 letter codes is the IBAN list。希望对您有所帮助。
您可以使用 pycountry
package.
自己轻松生成国家/地区
由于创建的 Country
模型上的 code
字段的最大长度为两个字符,因此您需要使用 alpha_2
代码。
对于这种事情,我通常使用 custom management command。也许添加一个检查以查看是否已经创建了任何对象,然后根据需要进行处理。
用法来自 shell python manage.py create_countries
from address.models import Country
from pycountry import countries
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = 'Initialize Country model'
def handle(self, *args, **kwargs):
create_countries = [
Country(name=country.name[:40], code=country.alpha_2)
for country in countries
]
Country.objects.bulk_create(create_countries)
self.stdout.write(f'Created {len(countries)} countries.\n')
如果生产服务器不是 运行 Python/Django,那么您可以使用 pycountry
创建包含相关数据的 CSV 文件。假设您使用的是 PostgreSQL,那么您可以使用 COPY FROM
command 来填充数据库。
import csv
from pycountry import countries
with open('countries.csv', mode='w') as countries_file:
# specify delimiter because some countries have a comma
writer = csv.writer(countries_file, delimiter='\t')
writer.writerow(['id', 'name', 'code'])
writer.writerows([
[index + 1, country.name, country.alpha_2]
for index, country in enumerate(countries)
])
您可以使用 django-countries 并在您的模型中包含一个 CountryField。这包括对模型的支持和表单的选择字段。
由于这是内置的,您可以将其包含在您的模型中,而不必担心播种 table。
我建议您编写一个简单的管理命令,从 pycountry into your address models (approach borrowed from here) 导入数据。 pycountry 是 ISO 标准国家列表的包装器 - 即,它与您将要获得的国家列表一样规范。
将所有国家/地区填充到您的 Country
模型中的 management command 看起来像这样:
import pycountry
from django.core.management.base import BaseCommand, CommandError
from address.models import Country
class Command(BaseCommand):
help = "Populates address.Country with data from pycountry."
def handle(self, *args, **options):
countries = [
Country(
code=country.alpha_2,
name=country.name[:40], # NOTE - concat to 40 chars because of limit on the model field
)
for country in pycountry.countries
]
Country.objects.bulk_create(countries)
self.stdout.write("Successfully added %s countries." % len(countries))
这将使用 ISO 国家/地区列表填充您的模型。
这里需要注意的是 address.Country.name
字段限制为 40 个字符(这对我来说似乎是一个有问题的设计决定,以及不使国家/地区代码唯一的决定 - 绝对是 ISO 2 字母代码是唯一的),因此上面的脚本会截断名称以适合。如果这对您来说是个问题,我建议您设置自己的地址模型,借鉴 django-address
并提高字符限制。
越简单越好。通过 django 文档,您可以创建数据迁移:https://docs.djangoproject.com/en/3.0/topics/migrations/#data-migrations
假设您的 models.py
的应用程序名称是 coops
,请执行以下操作:
第一个:
pip install django-countries
(我更喜欢 pipenv 安装)https://github.com/SmileyChris/django-countries
第二个:
- 将
django_countries
添加到 INSTALLED_APPS
第三名:
- 制作一个空的迁移文件:
python manage.py makemigrations --empty coops
第四:
- 编辑迁移文件,例如:
vi coops/migrations/0002_auto_20200205_0421.py
- 文件内容:
# Generated by Django 2.2 on 2020-02-05 04:21
from django.db import migrations
def init_countries(apps, schema_editor):
from django_countries import countries
from address.models import Country
countries = [
Country(code=code, name=name) for code, name in countries
]
Country.objects.bulk_create(countries)
class Migration(migrations.Migration):
dependencies = [
('coops', '0001_initial'),
]
operations = [
migrations.RunPython(init_countries),
]
第五名:
- 运行
python manage.py migrate
迁移后address_country table应该有如下数据:
In [1]: from address.models import *
In [2]: Country.objects.all()
Out[2]: <QuerySet [<Country: Afghanistan>, <Country: Albania>, <Country: Algeria>, <Country: American Samoa>, <Country: Andorra>, <Country: Angola>, <Country: Anguilla>, <Country: Antarctica>, <Country: Antigua and Barbuda>, <Country: Argentina>, <Country: Armenia>, <Country: Aruba>, <Country: Australia>, <Country: Austria>, <Country: Azerbaijan>, <Country: Bahamas>, <Country: Bahrain>, <Country: Bangladesh>, <Country: Barbados>, <Country: Belarus>, '...(remaining elements truncated)...']>
In [3]: Country.objects.all().count()
Out[3]: 249
我正在使用 Django 2.0、Python 3.7 和 MySql 5. 我最近安装了 django_address 模块。我注意到当我 运行 我的初始迁移基于我的 models.py 文件时...
from django.db import models
from address.models import AddressField
from phonenumber_field.modelfields import PhoneNumberField
class CoopType(models.Model):
name = models.CharField(max_length=200, null=False)
class Meta:
unique_together = ("name",)
class Coop(models.Model):
type = models.ForeignKey(CoopType, on_delete=None)
address = AddressField(on_delete=models.CASCADE)
enabled = models.BooleanField(default=True, null=False)
phone = PhoneNumberField(null=True)
email = models.EmailField(null=True)
web_site = models.TextField()
它创建了一些地址 tables,包括...
mysql> show create table address_country;
+-----------------+---------------------------------------------------+
| Table | Create Table |
+-----------------+---------------------------------------------------+
| address_country | CREATE TABLE `address_country` ( |
| | `id` int(11) NOT NULL AUTO_INCREMENT, |
| | `name` varchar(40) COLLATE utf8_bin NOT NULL, |
| | `code` varchar(2) COLLATE utf8_bin NOT NULL, |
| | PRIMARY KEY (`id`), |
| | UNIQUE KEY `name` (`name`) |
| | ) ENGINE=InnoDB |
| | DEFAULT CHARSET=utf8 COLLATE=utf8_bin |
+-----------------+---------------------------------------------------+
但是,这个table里面没有数据。模块生成的table有没有办法获取种子数据,还是需要自己去挖掘?
如上所述,您需要自己添加实际数据。您需要准备好并一次性上传。如果您只查找国家/地区数据,this is a good source. There is also a django app called django-countries which lets you have a lot more data and controls including flags, ISO codes etc. Another database with 3 letter codes is the IBAN list。希望对您有所帮助。
您可以使用 pycountry
package.
由于创建的 Country
模型上的 code
字段的最大长度为两个字符,因此您需要使用 alpha_2
代码。
对于这种事情,我通常使用 custom management command。也许添加一个检查以查看是否已经创建了任何对象,然后根据需要进行处理。
用法来自 shell python manage.py create_countries
from address.models import Country
from pycountry import countries
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = 'Initialize Country model'
def handle(self, *args, **kwargs):
create_countries = [
Country(name=country.name[:40], code=country.alpha_2)
for country in countries
]
Country.objects.bulk_create(create_countries)
self.stdout.write(f'Created {len(countries)} countries.\n')
如果生产服务器不是 运行 Python/Django,那么您可以使用 pycountry
创建包含相关数据的 CSV 文件。假设您使用的是 PostgreSQL,那么您可以使用 COPY FROM
command 来填充数据库。
import csv
from pycountry import countries
with open('countries.csv', mode='w') as countries_file:
# specify delimiter because some countries have a comma
writer = csv.writer(countries_file, delimiter='\t')
writer.writerow(['id', 'name', 'code'])
writer.writerows([
[index + 1, country.name, country.alpha_2]
for index, country in enumerate(countries)
])
您可以使用 django-countries 并在您的模型中包含一个 CountryField。这包括对模型的支持和表单的选择字段。
由于这是内置的,您可以将其包含在您的模型中,而不必担心播种 table。
我建议您编写一个简单的管理命令,从 pycountry into your address models (approach borrowed from here) 导入数据。 pycountry 是 ISO 标准国家列表的包装器 - 即,它与您将要获得的国家列表一样规范。
将所有国家/地区填充到您的 Country
模型中的 management command 看起来像这样:
import pycountry
from django.core.management.base import BaseCommand, CommandError
from address.models import Country
class Command(BaseCommand):
help = "Populates address.Country with data from pycountry."
def handle(self, *args, **options):
countries = [
Country(
code=country.alpha_2,
name=country.name[:40], # NOTE - concat to 40 chars because of limit on the model field
)
for country in pycountry.countries
]
Country.objects.bulk_create(countries)
self.stdout.write("Successfully added %s countries." % len(countries))
这将使用 ISO 国家/地区列表填充您的模型。
这里需要注意的是 address.Country.name
字段限制为 40 个字符(这对我来说似乎是一个有问题的设计决定,以及不使国家/地区代码唯一的决定 - 绝对是 ISO 2 字母代码是唯一的),因此上面的脚本会截断名称以适合。如果这对您来说是个问题,我建议您设置自己的地址模型,借鉴 django-address
并提高字符限制。
越简单越好。通过 django 文档,您可以创建数据迁移:https://docs.djangoproject.com/en/3.0/topics/migrations/#data-migrations
假设您的 models.py
的应用程序名称是 coops
,请执行以下操作:
第一个:
pip install django-countries
(我更喜欢 pipenv 安装)https://github.com/SmileyChris/django-countries
第二个:
- 将
django_countries
添加到INSTALLED_APPS
第三名:
- 制作一个空的迁移文件:
python manage.py makemigrations --empty coops
第四:
- 编辑迁移文件,例如:
vi coops/migrations/0002_auto_20200205_0421.py
- 文件内容:
# Generated by Django 2.2 on 2020-02-05 04:21
from django.db import migrations
def init_countries(apps, schema_editor):
from django_countries import countries
from address.models import Country
countries = [
Country(code=code, name=name) for code, name in countries
]
Country.objects.bulk_create(countries)
class Migration(migrations.Migration):
dependencies = [
('coops', '0001_initial'),
]
operations = [
migrations.RunPython(init_countries),
]
第五名:
- 运行
python manage.py migrate
迁移后address_country table应该有如下数据:
In [1]: from address.models import *
In [2]: Country.objects.all()
Out[2]: <QuerySet [<Country: Afghanistan>, <Country: Albania>, <Country: Algeria>, <Country: American Samoa>, <Country: Andorra>, <Country: Angola>, <Country: Anguilla>, <Country: Antarctica>, <Country: Antigua and Barbuda>, <Country: Argentina>, <Country: Armenia>, <Country: Aruba>, <Country: Australia>, <Country: Austria>, <Country: Azerbaijan>, <Country: Bahamas>, <Country: Bahrain>, <Country: Bangladesh>, <Country: Barbados>, <Country: Belarus>, '...(remaining elements truncated)...']>
In [3]: Country.objects.all().count()
Out[3]: 249