Импорт данных Django из файла JSON в БД не работает с OneToOneFields

В настоящее время я работаю над импортером, который позволяет мне импортировать json-файл из папки, которую я получаю с другого сервера. Пока я могу импортировать все обычные поля моей модели, но части, использующие OneToOneFields, не импортируются. Вместо этого я получаю следующее сообщение об ошибке:

Something went wrong saving this Facility: Test Facility
Field 'id' expected a number but got {'PrimaryAddress': '1234 Test Avenue', 'SecondaryAddress': '', 'City': 'Testcity', 'RegionOrState': 'CA', 'PostalCode': '12345', 'Geolocation': ''}.

Вот мой код, включая json, который я импортирую, и модель базы данных:

import os
import json
from data_import.models import Facility, FacilityAddress
from django.core.management.base import BaseCommand
from datetime import datetime
from jsontest.settings import BASE_DIR, STATIC_URL


class Command(BaseCommand):
    def import_facility_from_file(self):
        print(BASE_DIR)
        data_folder = os.path.join(BASE_DIR, 'import_data', 'resources')

        for data_file in os.listdir(data_folder):
            with open(os.path.join(data_folder, data_file), encoding='utf-8') as data_file:
                data = json.loads(data_file.read())
                for key, data_object in data.items():
                    Name = data_object.get('Name', None)
                    IssuedNumber = data_object.get('IssuedNumber', None)
                    AddressInfo = data_object.get('AddressInfo', None)

                    try:
                        facility, created = Facility.objects.get_or_create(
                            Name=Name,
                            IssuedNumber=IssuedNumber,
                            AddressInfo=AddressInfo
                        )
                        if created:
                            facility.save()
                            display_format = "\Facility, {}, has been saved."
                            print(display_format.format(facility))
                    except Exception as ex:
                        print(str(ex))
                        msg = "\n\nSomething went wrong saving this Facility: {}\n{}".format(Name, str(ex))
                        print(msg)


    def handle(self, *args, **options):
        """
        Call the function to import data
        """
        self.import_facility_from_file()
class FacilityAddress(models.Model):
    PrimaryAddress = models.CharField(max_length=50, null=True, blank=True)
    SecondaryAddress = models.CharField(max_length=50, null=True, blank=True)
    City = models.CharField(max_length=50, null=True, blank=True)
    RegionOrState = models.CharField(max_length=30, null=True, blank=True)
    PostalCode = models.CharField(max_length=20, null=True, blank=True)
    Geolocation = models.CharField(max_length=20, null=True, blank=True)


class Facility(models.Model):
    UUID = models.CharField(max_length=20, null=True, blank=True)
    Name = models.CharField(max_length=50, null=True, blank=True)
    admin_uid = models.OneToOneField(User, null=True, blank=True, on_delete=models.SET_NULL)
    AddressInfo = models.OneToOneField(FacilityAddress, null=True, blank=True, on_delete=models.SET_NULL)
    IssuedNumber = models.CharField(max_length=20, null=True, blank=True)
    mainimage = models.ImageField(null=True, blank=True)
    Capacity = models.IntegerField(null=True, blank=True)
    Licensee = models.CharField(max_length=30, null=True, blank=True)
    Email = models.EmailField(max_length=30, null=True, blank=True)
    AdministratorName = models.CharField(max_length=30, null=True, blank=True)
    Status = models.CharField(max_length=10, null=True, blank=True)
    TelephoneNumber = models.CharField(max_length=20, null=True, blank=True)
    ClosedTimestamp = models.IntegerField(null=True, blank=True)
    MostRecentLicenseTimestamp = models.IntegerField(null=True, blank=True)
    InspectionInfo = models.OneToOneField(FacilityInspectionInfo, null=True, blank=True, on_delete=models.SET_NULL)
    Complaints = models.OneToOneField(FacilityComplaints, null=True, blank=True, on_delete=models.SET_NULL)
{"00016ed7be4d872aseddsf6f36bfsdfd647f3eb41cadedd2130bdfsdfsdf6fbbbf24c2f1a64d2cf34ac4e03aaa30309816f98a7389b2bb324a2":{"UUID":"00016ed7be4d872aseddsf6f36bfsdfd647f3eb41cadedd2130bdfsdfsdf6fbbbf24c2f1a64d2cf34ac4e03aaa30309816f98a7389b2bb324a2","Name":"SENIOR CARE","IssuedNumber":"123456","Licensee":"SENIOR CARE","Email":"test@dfjksdajfkljklsd.com","AdministratorName":"Tester","TelephoneNumber":"(123) 456-789101112","AddressInfo":{"PrimaryAddress":"123 Test Road","SecondaryAddress":"","City":"Testcity","RegionOrState":"TESTSTATE","PostalCode":"12345","Geolocation":"11.1111,-11.1111"},"Capacity":1,"MostRecentLicenseTimestamp":1234567891,"ClosedTimestamp":0,"InspectionInfo":{"ComplaintRelatedVisits":0,"InspectionRelatedVisits":0,"NumberOfVisits":0,"LastVisitTimestamp":0},"Complaints":{"ComplaintsTypeA":0,"ComplaintsTypeB":0,"SubstantiatedAllegations":0,"TotalAllegations":0}},

Кто-нибудь знает, как я могу это исправить?

Если вы хотите создать и Facility, и FacilityAddress, вам нужен оператор get_or_create для обоих. Затем вы сохраняете переменную для созданного/извлеченного FacilityAddress и предоставляете ее Facility.

Пример:


facility_address, address_created = FacilityAddress.objects.get_or_create(
    PrimaryAddress=PrimaryAddress,
    SecondaryAddress=SecondaryAddress,
    City=City,
    RegionOrState=RegionOrState,
    PostalCode=PostalCode,
    Geolocation=Geolocation
)
facility, facility_created = Facility.objects.get_or_create(
    Name=Name,
    IssuedNumber=IssuedNumber,
    AddressInfo=facility_address
)

Этот код создает адрес объекта, если он не существует, и предоставляет объект, представляющий этот адрес, второму get_or_create.

Примечание: AddressInfo, вероятно, должен быть ForiegnKey, а не OneToOneField, если только невозможно существование двух объектов по одному адресу.

Вернуться на верх