Django中的models如何建立指向auth.User的外键?

XAS712
  • 59

我目前在做一个项目,有个保存用户通知的model如下:

class usrMes(models.Model):
    fromuser=models.ForeignKey(User,on_delete=models.PROTECT,related_name='id')
    touser=models.ForeignKey(User,on_delete=models.PROTECT,related_name='id')
    subject=models.CharField(max_length=100)
    content=models.CharField(max_length=2000)
    meslevel=models.IntegerField(default=0)
    ts=models.IntegerField(default=0)
    status=models.IntegerField(default=1)#0:已读; 1:未读; 
    class Meta:
        db_table = 'dj_usermes'

现在每次runserver都会提示:

TypeError: Direct assignment to the reverse side of a related set is prohibited. Use id.set() instead.

经过排查,即便是一个空的views.py也会引发该问题,于是怀疑models写的不对。
完整报错信息如下:

root@mzy7****:~/****# python36 manage.py runserver 0:8**1
Performing system checks...

Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x7f41172d8d90>
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/django/utils/autoreload.py", line 225, in wrapper
    fn(*args, **kwargs)
  File "/usr/local/lib/python3.6/site-packages/django/core/management/commands/runserver.py", line 120, in inner_run
    self.check(display_num_errors=True)
  File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 364, in check
    include_deployment_checks=include_deployment_checks,
  File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 351, in _run_checks
    return checks.run_checks(**kwargs)
  File "/usr/local/lib/python3.6/site-packages/django/core/checks/registry.py", line 73, in run_checks
    new_errors = check(app_configs=app_configs)
  File "/usr/local/lib/python3.6/site-packages/django/contrib/auth/checks.py", line 74, in check_user_model
    if isinstance(cls().is_anonymous, MethodType):
  File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py", line 480, in __init__
    _setattr(self, field.attname, val)
  File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 509, in __set__
    % self._get_set_deprecation_msg_params(),
TypeError: Direct assignment to the reverse side of a related set is prohibited. Use id.set() instead.

尝试百度解决但没有搜索到任何有价值的资料。
请问大家有尝试过用外键指向User吗?这里为什么不能正常运行?
Django版本2.0,Python3.6,Debian8.9 x64

回复
阅读 3.7k
1 个回答

应该是你定义的related_name和User的id属性发生了冲突.
如果你没有给外键定义related_name属性,那么反向引用的时候就是: User.usrMes_set.all()
你添加了related_name='id'后就成了: User.id.all(), 这样就和调用id属性User.id有冲突了.

另外对同一个model的两个外键,related_name不能重名

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏