Django使用ManyToMany报models无该属性AttributeError如何解决
报错原因
触发AttributeError: module 'django.db.models' has no attribute 'ManyToMany'的直接原因是字段名拼写错误:Django ORM中用来定义多对多关系的字段类是ManyToManyField,django.db.models模块下不存在名为ManyToMany的属性。
除此之外原代码还存在两处会引发后续运行异常的问题:
related_name参数值设置为listing,和当前字段名重名,会导致双向关联时的属性覆盖冲突,无法正常通过反向关联访问数据- 关联User模型的ForeignKey字段设置了
default="",外键字段存储的是关联模型的主键值(通常为整数),空字符串和字段类型不匹配,创建记录时会触发数据类型错误
修复方法
- 修正多对多字段的类名为
ManyToManyField - 将
related_name修改为语义化、无冲突的反向访问名称,比如watchlists - 删除ForeignKey字段的无效
default=""配置,如果需要允许WatchList不绑定用户,可以额外添加null=True, blank=True参数
修正后的模型代码如下:
class WatchList(models.Model): listing = models.ManyToManyField(Listings, blank=True, related_name="watchlists") user = models.ForeignKey(User, on_delete=models.CASCADE)
提示:如果
Listings模型的代码定义在WatchList模型之后,需要将字段参数中的Listings改为字符串形式"Listings",避免触发模型未定义的报错。
修改完成后,执行以下命令同步数据库表结构:
python manage.py makemigrations python manage.py migrate
迁移完成后即可正常实现双向关联访问:
- 正向访问(从WatchList查关联的Listing):调用
watchlist_instance.listing.all()获取对应 WatchList 下的所有 Listing 对象 - 反向访问(从Listing查关联的WatchList):调用
listing_instance.watchlists.all()获取包含当前 Listing 的所有 WatchList 对象
内容的提问来源于stack exchange,提问作者skateb2020
相关产品推荐
相关产品推荐

