Django 使用pk或其他方式通过命令行/脚本将现有ForeignKey分配给模型字段
我正在尝试导入此csv数据:Django 使用pk或其他方式通过命令行/脚本将现有ForeignKey分配给模型字段,django,python-3.x,django-models,Django,Python 3.x,Django Models,我正在尝试导入此csv数据: 1/30/1987,C152,6408H,CXO-CXO,1,0.5,1,,,,,,,,,,0.5,,,,, 4/29/1987,C172,97320,CXO-CXO,1,1,1,,,,,,,,,,1,,,,, 12/12/1987,C150,10002,CXO-CXO,1,1,1,,,,,,,,,,1,,,,, 11/12/1988,C150,10002,CXO-CXO,1,0.6,2,,,,,,,,,,0.6,,,,, 11/17/1988,C150,10002
1/30/1987,C152,6408H,CXO-CXO,1,0.5,1,,,,,,,,,,0.5,,,,,
4/29/1987,C172,97320,CXO-CXO,1,1,1,,,,,,,,,,1,,,,,
12/12/1987,C150,10002,CXO-CXO,1,1,1,,,,,,,,,,1,,,,,
11/12/1988,C150,10002,CXO-CXO,1,0.6,2,,,,,,,,,,0.6,,,,,
11/17/1988,C150,10002,CXO-CXO,1,1.1,3,,,,,,,,,,1.1,,,,,
9/9/1989,C150,10002,CXO-CXO,1,0.8,2,,,,,,,,,,0.8,,,,,
9/11/1989,C150,10002,CXO-CXO,1,0.7,1,,,,,,,,,,0.7,,,,,
9/18/1989,C150,10002,CXO-CXO,1,0.8,1,,,,,,,,,,0.8,,,,,
9/28/1989,C150,10002,CXO-CXO,1,0.7,3,,,,,,,,,,0.7,,,,,
9/29/1989,C150,10002,CXO-CXO,1,1,3,,,,,,,,,,1,,,,,
10/3/1989,C150,10002,CXO-CXO,1,0.6,5,,,,,,,,,,0.6,,,,,
使用此脚本:
import os.path
import sys
import csv
import django
import datetime
os.environ["DJANGO_SETTINGS_MODULE"] = "logbook.settings"
django.setup()
from flights.models import Flight, Aircraft, Approach
# converts values, if they exist, to boolean objects
def convertBool(row_id):
if row_id:
row_id = True
else:
row_id = False
return row_id
# assigns row_id as aircraft object
def assignAircraft(row_id):
aircraft = None
aircraft_queryset = Aircraft.objects.all()
if aircraft_queryset.filter(aircraft_type = row_id).exists():
pass
else:
aircraft = Aircraft(
aircraft_type = row_id,
)
aircraft.save()
aircraft = Aircraft(aircraft.pk)
return aircraft
# adds N to registration if needed
def editReg(row_id):
if row_id.startswith('N'):
pass
else:
row_id = 'N' + row_id
return row_id
#os agnostic file path
userhome = os.path.expanduser('~')
path = os.path.join(userhome, 'django_/logbook/', 'logbook.csv')
with open(path, 'r') as logbook:
reader = csv.reader(logbook)
next(reader) # skips header
for row in reader: # iterates rows
# date to python datetime object
date = datetime.datetime.strptime(row[0], '%m/%d/%Y').date()
row[0] = date
# makes any empty entry default to 0
for n, i in enumerate(row):
if i == '':
row[n]=0
aircraft = assignAircraft(row[1])
flight = Flight(
date = row[0],
aircraft = aircraft, # how do I make this assign an existing object from Aircraft.aircraft_type!?
aircraft_ident = editReg(row[2]),
route = row[3],
legs = row[4],
duration = row[5],
landings_day = int(row[6]),
landings_night = int(row[7]),
night = row[8],
instrument = row[9],
# approaches = row[10],
cross_country = convertBool(row[11]),
second_in_command = convertBool(row[12]),
pilot_in_command = convertBool(row[13]),
simulated_instrument = row[14],
instructor = convertBool(row[15]),
dual = convertBool(row[16]),
# # remarks = row[17],
simulator = convertBool(row[18]),
solo = convertBool(row[19]),
# flight_cost = row[20],
# expenses = row[21],
)
flight.save()
这就是错误:
Traceback (most recent call last):
File "csvimport.py", line 84, in <module>
solo = convertBool(row[19]),
File "/Users/blakepowell/django_/venv/lib/python3.6/site-packages/django/db/models/base.py", line 537, in __init__
setattr(self, field.name, rel_obj)
File "/Users/blakepowell/django_/venv/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 211, in __set__
self.field.remote_field.model._meta.object_name,
ValueError: Cannot assign "9576": "Flight.aircraft" must be a "Aircraft" instance.
目前,assignAircraft正在从新创建的实例返回pk。我读到有可能使用它的pk将一个现有的FK分配给一个模型,但还没有弄清楚
这就是我想要的解决方案:
行[1]将使用其pk或其他方式作为飞机实例插入Flightaircraft=Aircraft。您的代码没有意义。你刚刚在飞机上做了一个创造:
# you are creating an aircraft instance here
aircraft = Aircraft(aircraft_type = row_id)
# instance saved to database, all good so far
aircraft.save()
# why don't you return it?
return aircraft
你为什么不直接返回飞机实例呢?为什么要创建另一个未保存的飞机实例:
# What are you trying to do here? This is an unsaved aircraft instance
aircraft = Aircraft(aircraft.pk)
return aircraft
只发布相关代码。不要指望有人会仔细检查所有这些,为你找到一个bug。这种方法到底有什么意义?去掉多余的代码,但添加与型号类似的相关位assignAircraft的主要目的是只输入一个飞机实例,因为在CSV的2100行中,每个实例都有数百个。我正在尝试返回新创建的实例以在flightsaircraft=newinstancet中使用。这不会使它变得更清晰。谢谢您的帮助。我想我找到了错误。当一个新实例保存到飞机模型时,它只返回一个Aircraft.Aircraft_类型实例。我需要将第[1]行的每一次连续出现也传递到“return Aircrafter”(返回飞机)中,这里是+1,以便理解这一点,然后您可能需要使用get\u或\u create:。但要注意返回类型。