AttributeError:'ManyToManyField'对象没有属性'_m2m_reverse_name_cache'

Her*_*ere 6 python django django-models django-orm

我正在尝试将项目经理分配给员工.

  • 每个员工都可以成为项目经理.

  • 项目经理可以拥有多名员工.

  • 员工只能拥有1名项目经理.

但是,当我这样做 Employee.objects.get(name='HereHere').get_xxx()

我有 AttributeError: 'ManyToManyField' object has no attribute '_m2m_reverse_name_cache'

class Employee(models.Model):
    name = models.CharField(max_length=20, unique=True)
    pm = models.ManyToManyField('self', symmetrical=False, through='PM', related_name='related_to', )

    def add_pm(self, employee, ):
        pm, created = PM.objects.get_or_create(from_employee=self, to_employee__in=employee,)
        return pm

    def remove_pm(self, employee, ):
        PM.objects.filter(
            from_employee=self,
            to_employee=employee,
        ).delete()
        return

    def get_relationships(self, ):
        return self.pm.filter(
            to_employee__from_employee=self)   #<----- AttributeError: 'ManyToManyField' object has no attribute '_m2m_reverse_name_cache'

    def get_related_to(self,):
        return self.related_to.filter(
            from_employee__to_employee=self)    #<----- AttributeError: 'ManyToManyField' object has no attribute '_m2m_reverse_name_cache'


    def __str__(self):
        return '%s' % self.name


class PM(models.Model):
    from_employee = models.ForeignKey(Employee, related_name='from_employee')
    to_employee = models.ManyToManyField(Employee, related_name='to_employee') #<----- This cause the problem
Run Code Online (Sandbox Code Playgroud)

Bre*_*dan 7

我使用上面的代码创建了一个应用程序并设法重新创建该问题.

我尝试按照这里的建议将'self'切换为'Employee',并尝试on_delete=models.CASCADE在字段中调整其他一些东西(比如),但仍然实例化一个Employee对象并调用.pm它会引发错误.

我认为django期望你可以使用什么类作为throughManyToMany 的参数,它必须有两个外键,而不是外键和ManyToMany.

所以...

如果你切换到这个:

class PM(models.Model):
    from_employee = models.ForeignKey(Employee, related_name='from_employee')
    to_employee = models.ForeignKey(Employee, related_name='to_employee')
Run Code Online (Sandbox Code Playgroud)

有用.而这实际上是ManyToMany关系的正常模式 - 每个PM代表一个项目经理关系,而不是一个人.

或者,

您可以让项目经理成为从员工到员工的外键,命名managed_by为确保每个员工只能拥有一个项目经理.