Как получить id из другой таблицы в django?

Я пишу скрипт для наполнения таблиц базы данных. Мне нужно получить внешний ключ из таблицы City. В таблицы City 3 поля: id, name, reference. Внешний ключ мне нужен для таблицы Warehouses с полями id, name,reference, city_id ( внешний ключ ). Все данные я беру из API.

def refresh_warehouses():
    api_domain = 'https://api.novaposhta.ua'
    api_path = '/v2.0/json/Address/getWarehouses'

    api_data = {
        "modelName": "Address",
        "calledMethod": "getWarehouses",
        "methodProperties": {
            "Limit": "5"
        },
        'apiKey': settings.NOVA_POSHTA_API_KEY
    }

    response = requests.post(api_domain + api_path, json=api_data).json()

    if not response.get('success'):
        raise Exception(','.join(response.get('errors')))

    Warehouse.objects.all().delete()

    warehouses = []

    for item in response.get('data'):
        params = {
            'name': item.get('Description'),
            'reference': item.get('Ref'),
            'city_id': City.objects.get(name=item.get("CityDescription")).id,
            'delivery_method_id': 1
        }

        warehouses.append(Warehouse(**params))

    Warehouse.objects.bulk_create(warehouses)

После выполнения скрипта django выдает ошибку FOREIGN KEY constraint failed.

Подскажите как лучше взять id из таблицы City?


Ответы (1 шт):

Автор решения: hedgehogues

Чтобы получить id из таблицы City, вы можете использовать метод get менеджера объектов модели City. Он позволяет найти объект модели по заданному условию. В вашем случае условие может быть указанием значения поля name.

Вот как может выглядеть код:

city = City.objects.get(name=item.get("CityDescription"))
params = {
    'name': item.get('Description'),
    'reference': item.get('Ref'),
    'city_id': city.id,
    'delivery_method_id': 1
}

Обратите внимание, что если в таблице City не будет найден объект с заданным значением поля name, то будет выброшено исключение DoesNotExist. Поэтому стоит обернуть код в try-except блок и обработать это исключение.

В случае, если в таблице City может быть несколько объектов с одинаковым значением поля name, то стоит использовать метод filter менеджера объектов модели City, который вернет набор объектов, удовлетворяющих условию. В этом случае вам нужно будет выбрать один из найденных объектов, например, первый из них.

Вот как может выглядеть код:

try:
    city = City.objects.get(name=item.get("CityDescription"))
except City.DoesNotExist:
    # Обработка случая, когда не найдено ни одного объекта с указанным именем
except City.MultipleObjectsReturned:
    cities = City.objects.filter(name=item.get("CityDescription"))
    city = cities[0]

params = {
    'name': item.get('Description'),
    'reference': item.get('Ref'),
    'city_id': city.id,
    'delivery_method_id': 1
}

Обратите внимание, что в приведенном примере я использовал константы DoesNotExist и MultipleObjectsReturned из класса City. Они определены в Django и используются для обработки случаев, когда не удалось найти объект

Вариантом решения проблемы может быть также использование метода get_or_create менеджера объектов модели City. Он позволяет найти объект с указанными параметрами или, если такого объекта не существует, создать новый объект с указанными параметрами. В данном случае вам нужно будет указать имя города как параметры метода.

Вот как может выглядеть код:

city, created = City.objects.get_or_create(name=item.get("CityDescription"))

params = {
    'name': item.get('Description'),
    'reference': item.get('Ref'),
    'city_id': city.id,
    'delivery_method_id': 1
}

Обратите внимание, что метод get_or_create возвращает кортеж, содержащий найденный или созданный объект и флаг, указывающий, был ли создан новый объект. В приведенном примере я распаковал этот кортеж в переменные city и created

→ Ссылка