Предоставляет ли модуль django_address способ получения начальных данных о стране? - PullRequest
6 голосов
/ 27 января 2020

Я использую 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()

Он создал несколько адресных таблиц, в том числе ...

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             |
+-----------------+---------------------------------------------------+

Однако эта таблица не имеет данных в нем. Есть ли способ получить начальные данные для таблицы, сгенерированной модулем, или мне нужно откопать ее самостоятельно?

Ответы [ 5 ]

4 голосов
/ 30 января 2020

Вы можете самостоятельно создавать страны с помощью пакета pycountry .

Поскольку поле code в создаваемой модели Country имеет максимальную длину два символа, тогда вы захотите использовать код alpha_2.

Я обычно использую настраиваемую команду управления для такого рода вещей. Может быть, добавьте проверку, чтобы увидеть, были ли какие-либо объекты уже созданы, затем обработайте их так, как вам хочется.

Использование из оболочки 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 для заполнения базы данных.

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)
    ])
0 голосов
/ 05 февраля 2020

Просто лучше. С помощью django do c вы можете создать миграцию данных: https://docs.djangoproject.com/en/3.0/topics/migrations/#data -migrations

Предположите, что имя вашего приложения models.py равно coops, сделайте что-нибудь как это:

Первый:

Второй:

  • Добавить django_countries к INSTALLED_APPS

Третье:

  • Создать пустой файл миграции: python manage.py makemigrations --empty coops

Forth:

  • Отредактируйте файл миграции, например: 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),
    ]

Пятый:

  • run python manage.py migrate

После переноса таблица address_country должна иметь следующие данные:

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
0 голосов
/ 01 февраля 2020

Я бы предложил вам написать простую команду управления, которая импортирует данные из pycountry в ваши модели адресов (подход заимствован из здесь ). pycountry - это оболочка для стандартного списка стран ИСО, т. е. список стран, которые вы собираетесь получить, примерно такой же канонический.

A команда управления для заполнения всех стран ваша модель Country будет выглядеть примерно так:

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 определенно уникально), поэтому скрипт выше усекает имя до нужного. Если это проблема для вас, я предлагаю вам настроить свои собственные модели адресов, заимствуя у django-address и увеличивая количество символов.

0 голосов
/ 31 января 2020

Вы можете использовать django -стран и включить CountryField в вашу модель. Это включает в себя поддержку обеих моделей и поле выбора для форм.

Поскольку это встроено, вы можете просто включить это в свою модель, не беспокоясь о заполнении таблицы.

0 голосов
/ 30 января 2020

Как уже говорилось выше, вам нужно самим добавлять фактические данные. Вам нужно будет подготовить его и загрузить один раз. Если вы ищете только данные по стране, это хороший источник . Существует также приложение django под названием django -countries , которое позволяет вам иметь гораздо больше данных и элементов управления, включая флаги, коды ISO и т. Д. c. Другая база данных с трехбуквенными кодами - список IBAN . Надеюсь, это поможет.

...