来自外键的Django模型实例

时间:2013-11-24 20:51:36

标签: django foreign-keys instance

我正在使用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。 Dbshel​​l实用程序确实显示银行表有一个外国禁令,指的是车辆表,通过银行(id)。

由于我没有使用此特定部分的表单,我认为无论是否使用ModelForm都无关紧要。

当前场景:Excel文件将FBANK作为单元格值。在银行表中存在一条记录,其名称列中包含FBANK,id = 2。 python行是:

def bank(value):
    return Banks.objects.get(name=value).id

使用上面的行,错误是: 无法分配“2”:“Vehicles.bank”必须是“银行”实例。

如果我在结尾删除“.id”,则错误是: 匹配查询的银行不存在。

感谢您的帮助。 里卡多

2 个答案:

答案 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()

是个好主意。