Django模型中的m2m“通过”字段引发此错误:“m2m字段”对象没有属性“\u m2m\u reverse\u name\u cache”

2024-10-03 09:17:11 发布

您现在位置:Python中文网/ 问答频道 /正文

嘿,伙计们,我正试图添加一个m2mthrough字段,以便让助手像department.assistants.all()一样调用我的“部门”模型,但在这样做时,我遇到了这个错误AttributeError: 'ManyToManyField' object has no attribute '_m2m_reverse_name_cache'

这是我的模型:

class Department(models.Model):
    id                  = models.BigAutoField(primary_key=True)
    user                = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    assistants          = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Assistants', related_name='dep_assistants', 
                            symmetrical=False)

class Assistants(models.Model):
    id                  = models.BigAutoField(primary_key=True)
    department          = models.ForeignKey(Department, related_name='of_department', on_delete=models.CASCADE)
    assistant           = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='dt_assistant', 
                            verbose_name="Department Assistant", on_delete=models.CASCADE)
    added               = models.DateTimeField(auto_now_add=True)

我对这个概念很陌生。有人能告诉我我做错了什么吗

谢谢


Tags: name模型authtruemodelsettingsonmodels
2条回答

如果一个助理只涉及一个部门,这就是一对多的关系。(一个部门有许多助理)在代码中是:

class Assistant(models.Model):
    ...
    department = models.ForeignKey(Department)

不需要关于部门的特别参考资料。要获得所有助理:

assistants = models.Assistant.objects.filter(department=department)

或在类部门上创建属性:

@property
def assistants(self):
    return models.Assistant.objects.filter(department=self)

如果一个助理涉及多个部门(每个部门有多个助理),则是多对多关系,他们之间应该有额外的等级:

class Assignment(models.Model):
    assistant = models.ForeignKey(Assistant)
    department = models.ForeignKey(Department)

class Department(models.Model):
    ...
    assignment= models.ForeignKey(Assignment)

class Assistant(models.Model):
    ...
    assignment = models.ForeignKey(Assignment)

因此,在这里查询该部门的助理:

assistants = models.Assistant.objects.filter(
    assignment__in=models.Assignment.objects.filter(
        department=department
    )
)

根据您定义模型的方式,这些查询似乎太令人困惑了。尝试下面如何定义模型,然后尝试查询

您没有在多对多字段定义中提到through_字段属性。检查文档:https://docs.djangoproject.com/en/3.2/ref/models/fields/#django.db.models.ManyToManyField

class Department(models.Model):
    # i think this is not needed. Also id is a protected keyword in python.
    # id                  = models.BigAutoField(primary_key=True)
    user                = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    assistants          = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Assistants', 
                                                 related_name='departments', through_fields=("department", "assistant"))

# model name should never be prural. It is singluar becuase it is the name of the object.
class Assistant(models.Model):
    # i think this is not needed. Also id is a protected keyword in python.
    # id                  = models.BigAutoField(primary_key=True)
    department          = models.ForeignKey(Department, on_delete=models.CASCADE)
    assistant           = models.ForeignKey(settings.AUTH_USER_MODEL, verbose_name="Department Assistant", on_delete=models.CASCADE)
    added               = models.DateTimeField(auto_now_add=True)


# how to query assistants from departments
# you will get objects of User model
qs = department.assistants.all()


# how to query departments from assistants
# you will get objects of Department model
qs = user.departments.all()


# If you want to query the Assistant model

# from department object
qs = department.assistant_set.all()

# from assistant object
qs = user.assistant_set.all()

# in either case you will get the objects of Assistant model
for i in qs:
    print(i.added, i.department, i.assistant)

试试这个,如果你仍然得到错误,请告诉我

我的建议是将助手模型上的assistant字段命名为user。这样,您就不需要在多对多字段上定义through_field

相关问题 更多 >