Django 3.2中如何用数组初始化模型的ManyToMany多对多字段
错误原因分析
- 第一个
AttributeError报错核心原因:Django的ManyToMany字段依赖主模型实例的主键完成关联表映射,你在模型__init__方法中还未完成实例初始化、更未将实例写入数据库生成主键时,就尝试操作多对多关联管理器,必然会触发属性缺失错误。 - 第二个
TypeError报错是基础语法错误:Python中给set集合添加元素需要调用add()方法,你写的cc_set(cc)是把set对象当做函数调用,自然会触发不可调用的报错。
正确实现方式
直接用多对多管理器自带的set()方法即可批量设置关联值,不需要手动循环创建集合,同时要避免使用可变对象作为函数默认参数的Python常见坑:
def create_account(self, user, vendor, crypto_currencies_arr=None, max_transactions=DEFAULT_MAX_BUY_TRANSACTIONS): # 处理默认参数,避免可变对象默认值的全局复用问题 if crypto_currencies_arr is None: crypto_currencies_arr = [] # 先创建主模型实例并保存,生成主键 a = Account( user=user, vendor=vendor, max_transactions=max_transactions ) a.save() # 直接用set方法批量设置多对多关联,参数直接传数组即可 a.crypto_currencies.set(crypto_currencies_arr) # 多对多的set操作不需要额外调用主模型的save方法,此处可以省略 return a
额外说明
- 如果你需要在原有多对多关联的基础上追加元素,而不是覆盖原有值,可以用
a.crypto_currencies.add(*crypto_currencies_arr),直接把数组解包作为参数传入即可,不需要循环逐个添加。 - 多对多字段的增删改操作都是直接操作中间关联表,调用
set()/add()/remove()等方法后会立即生效,不需要再调用主模型的save()方法。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

