来自外键的Django模型实例
我正在使用xlrd阅读Excel。其中一列具有银行名称,该名称通过外键链接到车辆模型。xlrd读取完一行后,应将该记录保存到vehicle表中。但是,获取Vehicles.bank必须是Banks实例的实际pk值和错误 在检查了几十个与此问题相关的问题后,我发现这是最相似的一个,但仍然没有得到预期的结果 相关车型部分如下所示:来自外键的Django模型实例,django,foreign-keys,instance,Django,Foreign Keys,Instance,我正在使用xlrd阅读Excel。其中一列具有银行名称,该名称通过外键链接到车辆模型。xlrd读取完一行后,应将该记录保存到vehicle表中。但是,获取Vehicles.bank必须是Banks实例的实际pk值和错误 在检查了几十个与此问题相关的问题后,我发现这是最相似的一个,但仍然没有得到预期的结果 相关车型部分如下所示: class Vehicles(models.Model): stock = models.CharField(max_length=10, blank=False
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实用程序确实显示了banks表有一个通过banks(id)引用vehicles表的外来约束
因为我没有为这个特定的部分使用表单,所以我认为是否使用ModelForm并不重要
当前场景:Excel文件将FBANK作为单元格值。banks表中有一条现有记录,其名称列中包含FBANK,id=2。python行是:
def bank(value):
return Banks.objects.get(name=value).id
对于上述行,错误为:
无法分配“2”:“Vehicles.bank”必须是“Banks”实例
如果我删除结尾处的“.id”,则错误为:
匹配查询的银行不存在
谢谢你的帮助。
Ricardo当您要将银行实例分配给车辆模型实例时,应该返回银行实例;因此,bank()方法的返回值末尾不应该有.id部分 其次,如果它说找不到Banks实例,那么您应该检查
value
参数的值,看看它是什么,然后尝试手动从数据库执行Banks.objects.get。如果找不到,那么除了不正确地使用Django ORM之外,可能还有其他原因
将实例分配给Django中的其他实例时,例如,为车辆设置库时,它必须是模型的实例,而不是模型的id或pk值;这在您在问题中引用的另一个StackOverflow问题中有说明。当您要将银行实例分配给车辆模型实例时,应返回银行实例;因此,bank()方法的返回值末尾不应该有.id部分 其次,如果它说找不到Banks实例,那么您应该检查
value
参数的值,看看它是什么,然后尝试手动从数据库执行Banks.objects.get。如果找不到,那么除了不正确地使用Django ORM之外,可能还有其他原因
将实例分配给Django中的其他实例时,例如,为车辆设置库时,它必须是模型的实例,而不是模型的id或pk值;这在您在问题中引用的另一个StackOverflow问题中有说明。保存车辆时,您需要通过带有相应银行名称的银行实例。请参见示例,我假设您的所有数据都位于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文档中询问“在模型类上添加classmethod”,则情况并非如此,因为您只是在为模型使用内置方法。在某些情况下,您可以使用自定义方法创建新模型,但如果必须为新实例传递许多默认属性,我会这样做
此外,还可以使用save()创建和保存新的模型实例:
它相当长,您需要始终记住调用.save(),因此最好使用.create()在保存车辆时,您需要传递带有相应银行名称的银行实例。请参见示例,我假设您的所有数据都位于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文档中询问“在模型类上添加classmethod”,则情况并非如此,因为您只是在为模型使用内置方法。在某些情况下,您可以使用自定义方法创建新模型,但如果必须为新实例传递许多默认属性,我会这样做
此外,还可以使用save()创建和保存新的模型实例:
它很长,您需要始终记住调用.save(),因此最好使用.create()谢谢@nickzam。在测试了这两个选项之后,我最终使用了get_bank_实例选项。问题:我发现很难在Django页面上获得类似选项的可用性这样的文档。明确地说,这并不表示与这样的选项相关的任何内容。更重要的是,如果我进行搜索,确实有多个页面,但没有具体的内容(或者至少对我来说很容易确定“哦,我需要做X或Y”。对于这种情况,您有什么建议吗?再次感谢。get_bank_instance只是我创建的一个帮助函数,用于说明如何返回模型实例。您可能应该在shell中查看和使用一点(运行manage.py shell并导入您的模型)使用django模型和实例。感谢链接。实际上,我使用的编码块与您添加的类似(每个字段1行),因为有些字段需要验证,而其他字段也有外键。最重要的是,有些字段是必需的,所以如果Excel文件的值为空,或者验证不正确,或者外键不存在,我想警告用户,不要创建该记录。谢谢@nickzam。测试这两个选项后,我最后使用了get_bank_实例选项。问题:我发现很难获得Django页面上类似选项的可用性这样的文档。特别是没有