Как обрабатывать отношения «Многие ко многим» в Django без промежуточной таблицы?

#django #django-models #m2m

Вопрос:

Я унаследовал странную структуру таблиц:

 class Customer(models.Model):
    account_number = models.CharField()

class Subscription(models.Model):
    account_number = models.CharField()
 

Таким образом, модели клиентов и подписки связаны номерами их учетных записей. У каждого клиента может быть несколько подписок, и у каждой подписки может быть несколько клиентов, но нет промежуточной таблицы; нет таблицы «Учетная запись». Как мне справиться с подобными вещами? Если у меня есть набор запросов по подписке, как мне получить соответствующий набор запросов клиентов, не выполняя ужасно длинный запрос, такой как

 customers = Customer.objects.filter(account_number__in=list(subscriptions.values_list('account_number', flat=True)))
 

Я пытаюсь избежать этого, потому что это создаст массивный запрос, выполнение которого займет очень много времени.

Ответ №1:

Поскольку в нем нет таблицы m2m, это, вероятно, лучший способ сделать это. Однако вы можете немного оптимизировать запрос, чтобы использовать Django для использования подзапроса вместо списка номеров счетов в инструкции where.

 subs = subscriptions.only('account_number').all()
customers = Customer.objects.filter(account_number__in=subs) 

# if you print out the query you should see a subquery in the query where statement
print(customers.query)
 

Комментарии:

1. Спасибо! Однако подзапрос, к которому это приводит, на самом деле неверен — он выбирает идентификатор подписки вместо идентификатора учетной записи. Но бит .only («номер учетной записи») экономит некоторое время, так что спасибо; я забыл, что это существует.