Django多对多关系查询报错:'User'对象无'room_set'属性
Django多对多关系查询报错解决方案
问题背景
你定义了如下User模型:
class User(AbstractBaseUser, PermissionsMixin): email = models.EmailField(unique=True, max_length=255) mobile = PhoneNumberField(null=True) username = models.CharField(null=False, unique=True, max_length=255) is_staff = models.BooleanField(default=False) is_superuser = models.BooleanField(default=False) is_active = models.BooleanField(default=False)
该模型与Room模型为多对多关系,Room模型定义如下:
class Room(Base): name = models.CharField(unique=True, max_length=255) room_type = models.CharField(max_length=50, null=True) users = models.ManyToManyField(User, related_name='users')
当执行查询语句rooms = user.room_set.all()时,出现错误:
AttributeError: 'User' object has no attribute 'room_set'
错误原因
问题出在Room模型的ManyToManyField里设置的**related_name='users'**。
在Django中,默认情况下,反向关联的名称是模型名_set(比如这里默认应该是room_set),但一旦你显式指定了related_name,就会彻底覆盖这个默认的反向关联名称。你这里把用户到房间的反向关联命名为users,所以原来的room_set就不再存在了,这就是报错的核心原因。
解决方法
有两种可行的解决方式:
- 方式一:使用指定的related_name查询
直接用你设置的related_name来获取用户关联的房间,把查询代码改成:rooms = user.users.all() - 方式二:修改related_name为更合理的名称(推荐)
考虑到users这个名称存在歧义(用户对象的users属性看起来像是用户集合,而非房间集合),建议把Room模型里的related_name改成语义更清晰的名字,比如rooms:
修改后,你就可以用users = models.ManyToManyField(User, related_name='rooms')user.rooms.all()来查询用户关联的所有房间,这样的命名更符合直觉,代码可读性也更高。
内容的提问来源于stack exchange,提问作者Melissa Stewart
相关产品推荐
相关产品推荐

