我正在使用xlrd阅读Excel。其中一列具有银行名称,该名称通过外键链接到车辆模型。当xlrd完成读取行时,它应该将该记录保存到车辆表中。但是,获取Vehicle.bank必须为Banks实例的实际pk值和错误。
在检查了几个与此问题相关的问题之后,我发现这个问题最为one,但我仍然没有得到预期的结果。
相关车辆型号部分如下:
class Vehicles(models.Model):
stock = models.CharField(max_length=10, blank=False, db_index=True)
vin = models.CharField(max_length=17, blank=False, db_index=True)
sold = models.DateField(blank=True, null=True, db_index=True)
origin = models.CharField(max_length=10, blank=False, db_index=True)
bank = models.ForeignKey('banks.Banks', db_column='bank', null=True)
我正在使用python 2.7,django 1.5.4和Postgresql 9.2.5。 Dbshell实用程序确实显示银行表有一个外国禁令,指的是车辆表,通过银行(id)。
由于我没有使用此特定部分的表单,我认为无论是否使用ModelForm都无关紧要。
当前场景:Excel文件将FBANK作为单元格值。在银行表中存在一条记录,其名称列中包含FBANK,id = 2。 python行是:
def bank(value):
return Banks.objects.get(name=value).id
使用上面的行,错误是: 无法分配“2”:“Vehicles.bank”必须是“银行”实例。
如果我在结尾删除“.id”,则错误是: 匹配查询的银行不存在。
感谢您的帮助。 里卡多
答案 0 :(得分:0)
如果要将Banks实例分配给Vehicle模型实例,则应该返回它;所以你不应该将.id部分放在bank()方法的返回值的末尾。
其次,如果它说它没有找到Banks实例,那么你应该检查value
参数的值以查看它是什么,并尝试手动执行Banks.objects.get来自您的数据库。如果找不到它,那么除了错误地使用Django ORM之外,还有其他原因。
当您将实例分配给Django中的其他实例时,例如为车辆设置Bank,它必须是模型的实例,而不是模型的id或pk值;这在您在问题中引用的其他StackOverflow问题中说明。
答案 1 :(得分:0)
保存车辆时,您需要使用相应的银行名称传递Banks实例。参见示例,我假设您将相应单元格中的所有数据从0到4,替换为您自己的单元格数字:
def get_bank_instance(bank_name):
try:
bank = Banks.objects.get(name=bank_name)
except Banks.DoesNotExist:
return None
return bank
# reading excel file here, we have list of cells in a row
for cell in cells:
bank = get_bank_instance(cell[4])
if bank:
# get other cells values to be saved in Vehicles
stock, vin, sold, origin = cell[0], cell[1], cell[2], cell[3]
Vehicles.create(bank=bank, stock=stock, vin=vin, sold=sold, origin=origin)
您还可以直接创建通过银行ID的车辆的保存实例:
b_id = Banks.objects.get(name=bank_name).id
Vehicles.create(bank_id=b_id, stock=stock, vin=vin, sold=sold, origin=origin)
更新: create()是一个内置的模型方法,用于创建和保存到数据库模型实例中。如果您在Django文档中询问“在模型类上添加类方法”,则情况并非如此,因为您只是使用模型的内置方法。在某些情况下,您可以使用自定义方法来创建新模型,但如果我必须为新实例传递大量默认属性,我会这样做。
此外,可以使用save():
创建和保存新模型实例bank_instance = Banks.objects.get(name=bank_name)
vehicle = Vehicles()
vehicle.bank = bank_instance
vehicle.stock = stock
vehicle.vin = vin
vehicle.sold = sold
vehicle.origin = origin
# without save() data will not be saved to db!
vehicle.save()
这很长,你总是需要记得调用.save(),所以使用.create()
是个好主意。