Импорт данных 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
, если только невозможно существование двух объектов по одному адресу.