我使用Python字典将字符串映射到Django字段。我想更新或分配字段的值。
self.sheet_headers_2_fields = {
'Index': self.index,
'Device Model': self.model,
'MAC address': self.mac_address,
'IP Address': self.ip_address,
}
for sheet_header, model_field in self.sheet_headers_2_fields.items():
model_field = item.get_field_value(sheet_header)
我使用字典是为了在添加更多字段时更容易将字符串映射到字段。目前,这只是覆盖model_field,而不是将其分配给相应的字段,因此,模型没有更新。
为什么不工作?我知道Python通过引用传递-我的猜测是,因为model_field
(一个django字段)不是item.get_field_value(sheet_header)
(一个str)的相同类型,它覆盖到引用而不是更新值。
我怎样才能达到我想要的,要么用字典,要么用其他方法?
当您执行以下操作时:
self.sheet_headers_2_fields = {
'Index': self.index,
'Device Model': self.model,
'MAC address': self.mac_address,
'IP Address': self.ip_address,
}
这些self.index
,self.model
等不作为引用存储,而是将它们的值放入字典中。
所以我们写入:
self.index = 1
self.model = 2
self.mac_address = 3
self.ip_address = 4
然后翻译成:
self.sheet_headers_2_fields = {
'Index': 1,
'Device Model': 2,
'MAC address': 3,
'IP Address': 4,
}
话是这么说的,model_field = item.get_field_value(sheet_header)
不能特别用于不可变的字段(例如str
),因为这些类型的对象每次都会被覆盖(这意味着在某些时候,我们与self.attr
的连接已经丢失)。
- 但是如果字段是可变的,例如
list
,那么当然列表操作,例如append
(注意不要使用相同的=
操作,因为这会将堆栈变量指向不同的堆存储,从而失去对self.attr
的访问)将针对完全相同的对象。覆盖不会发生,因此你应该看到它反映在你的字段。
替代解决方案:setattr的使用
不映射例如self.mac_address
,只需映射名称"mac_address"
,然后使用setattr
来更新该字段。
class MyModel:
def __init__(self):
self.index = None
self.model = None
self.mac_address = None
self.ip_address = None
self.sheet_headers_2_fields = {
'Index': 'index',
'Device Model': 'model',
'MAC address': 'mac_address',
'IP Address': 'ip_address',
}
for sheet_header, model_field in self.sheet_headers_2_fields.items():
setattr(self, model_field, item.get(sheet_header)) # This now translates to e.g. self.mac_address = item.get("MAC address")
item = {
'Index': 1,
'Device Model': 'ABC123',
'MAC address': '1A-2B-3C-4D-5E-6F',
'IP Address': '127.0.0.1',
}
obj = MyModel()
print(f"{obj.sheet_headers_2_fields=}")
print(f"{obj.index=}")
print(f"{obj.model=}")
print(f"{obj.mac_address=}")
print(f"{obj.ip_address=}")
输出:
obj.sheet_headers_2_fields={'Index': 'index', 'Device Model': 'model', 'MAC address': 'mac_address', 'IP Address': 'ip_address'}
obj.index=1
obj.model='ABC123'
obj.mac_address='1A-2B-3C-4D-5E-6F'
obj.ip_address='127.0.0.1'