Как получить итерируемую коллекцию (queryset) из более чем одного поля ManyToManyField в Django?
Я хочу получить список врачей из клиник, основанных на определенном городе. Я разработал обходной путь, но он кажется дорогостоящим, поскольку я использую для этого цикл.
Модель клиники:
class Clinic(models.Model):
clinic_name = models.CharField(max_length=255)
address = models.CharField(max_length=255, null=True, blank=True)
doctor = models.ManyToManyField(Doctor, blank=True)
city = models.ForeignKey(City, on_delete=models.CASCADE)
latitude = models.CharField(max_length=255, null=True, blank=True)
longtitude = models.CharField(max_length=255, null=True, blank=True)
active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.clinic_name
Модель города:
class City(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
Модель доктора:
class Doctor(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True, related_name="doctor")
speciality = models.ManyToManyField(Speciality, blank=True)
service = models.ManyToManyField(Service, blank=True)
condition = models.ManyToManyField(Condition, blank=True)
def __str__(self):
return f"{self.title} {self.user.full_name}"
Мой обходной путь:
>>> my_city = City.objects.get(name='Kabul')
>>> clinics = Clinic.objects.filter(city=city)
>>> doctor_list = []
>>> for clinic in clinics:
doctor_list.extend(clinic.doctor.all())
>>> doctor_list
[<Doctor: Dr. Doctor Khan One>, <Doctor: Prof. Doctor Khan Two>, <Doctor: Dr. Doctor Khan One>, <Doctor: Dr. Doctor Khan One>]
>>> the_result = set(doctor_list)
>>> new_doctor_list = list(the_result)
>>> new_doctor_list
[<Doctor: Dr. Doctor Khan One>, <Doctor: Prof. Doctor Khan Two>]
Вы можете получить итератор:
Doctor.objects.filter(clinic__city__name='Kabul').iterator()
или все объекты:
Doctor.objects.filter(clinic__city__name='Kabul').all()
Пояснение: Фильтр ищет всех врачей, которые содержат клинику, содержащую город с названием 'Кабул'