首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >django模型中的m2m 'through‘字段抛出此错误:'M2M m2m’对象没有属性'_m2m_reverse_name_cache‘

django模型中的m2m 'through‘字段抛出此错误:'M2M m2m’对象没有属性'_m2m_reverse_name_cache‘
EN

Stack Overflow用户
提问于 2021-05-09 15:33:11
回答 2查看 104关注 0票数 2

嘿,伙计们,我正在尝试添加一个m2m through字段,以便在我的“部门”模型中有像department.assistants.all()一样的呼叫助手,但在这样做的过程中,我得到了这个错误AttributeError: 'ManyToManyField' object has no attribute '_m2m_reverse_name_cache'

这是我的模型:

代码语言:javascript
复制
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)

我对这个概念还很陌生。有人能告诉我我哪里做错了吗?

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-14 23:08:46

按照你定义模型的方式,查询似乎太混乱了。尝试下面定义模型的方式,然后尝试查询。

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

代码语言:javascript
复制
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模型上的assistant字段命名为user。这样,您就不需要在多对多字段上定义through_field

票数 1
EN

Stack Overflow用户

发布于 2021-05-11 17:29:15

如果一个助理只与一个部门相关-这是一对多关系。(一个部门有许多助手)在代码中应该是:

代码语言:javascript
复制
class Assistant(models.Model):
    ...
    department = models.ForeignKey(Department)

不需要在部门上有特殊的参考。要获取所有助理:

代码语言:javascript
复制
assistants = models.Assistant.objects.filter(department=department)

或者在类Department上创建一个属性:

代码语言:javascript
复制
@property
def assistants(self):
    return models.Assistant.objects.filter(department=self)

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

代码语言:javascript
复制
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)

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

代码语言:javascript
复制
assistants = models.Assistant.objects.filter(
    assignment__in=models.Assignment.objects.filter(
        department=department
    )
)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67455288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档