在 Django 中为多对多字段冲突反向访问器和查询?

Posted

技术标签:

【中文标题】在 Django 中为多对多字段冲突反向访问器和查询?【英文标题】:***ing reverse accessors and queries in Django for many to many field? 【发布时间】:2021-07-15 09:59:29 【问题描述】:
from django.db import models


class Appointment(models.Model):
    doctors = models.ManyToManyField('Doctor', through='AppointmentAccess', related_name='appointments')


class Doctor(models.Model):
    appointments = models.ManyToManyField('Appointment', through='AppointmentAccess', related_name='doctors')

我收到以下错误:

core.Appointments.doctors: (fields.E302) Reverse accessor for 'PatientProfile.users' ***es with field name 'Doctor.appointments'.
        HINT: Rename field 'Doctor.appointments', or add/change a related_name argument to the definition for field 'Appointment.doctors'.
core.Appointment.doctors: (fields.E303) Reverse query name for 'Doctor.appointments' ***es with field name 'Appointment.doctors'.
        HINT: Rename field 'Doctor.appointments', or add/change a related_name argument to the definition for field 'Appointment.doctors'.
core.Doctor.appointments: (fields.E302) Reverse accessor for 'Doctor.appointments' ***es with field name 'Appointments.doctors'.
        HINT: Rename field 'Appointment.doctors', or add/change a related_name argument to the definition for field 'Doctor.appointments'.
core.User.patient_profiles: (fields.E303) Reverse query name for 'Doctor.appointments' ***es with field name 'Appointments.doctors'.
        HINT: Rename field 'Appointments.doctors', or add/change a related_name argument to the definition for field 'Doctor.appointments'.

为什么?有人可以帮我理解这个错误吗?应该通过 AppointmentAccess 表跟踪多对多字段,而不是生成新的中间表。相关姓名预约与医生有何冲突?

【问题讨论】:

为什么两个模型都需要指定m2m?只需在其中一个中指定即可。 【参考方案1】:

您在两个模型中都指定了多对多关系。这不是必需的,因为 Django 会自动向关系中的其他模型添加反向关系,因此您可以简单地编写:

class Appointment(models.Model):
    # Remove below line
    doctors = models.ManyToManyField('Doctor', through='AppointmentAccess', related_name='appointments')
    ...


class Doctor(models.Model):
    appointments = models.ManyToManyField('Appointment', through='AppointmentAccess', related_name='doctors')

现在既然你已经设置了related_name(如果你没有默认设置为doctor_set,即小写的型号名称)如果你有一个Appointment的实例appointment你可以简单地写:

for doctor in appointment.doctors.all():
    print(doctor)

【讨论】:

以上是关于在 Django 中为多对多字段冲突反向访问器和查询?的主要内容,如果未能解决你的问题,请参考以下文章

Django admin - 如何在自定义管理表单中为多对多字段添加绿色加号

如何在 Rails 中为多对多关系(和中间表)做一个选择字段?

如何在 Django 中向多对多关系中添加字段?

在 Sequelize.js 中为多对多关系添加默认角色

如何在 Rails 4.2 中为多对多关联创建表单

如何在 Rails 4 中为多对多关联制作带有子表单的表单?