Получить все значения из Django QuerySet, а также дополнительные поля из связанной модели - PullRequest
0 голосов
/ 05 октября 2018

Мне было интересно, есть ли ярлык для получения всех полей из модели Django и определения только дополнительных полей, которые извлекаются посредством объединения (или нескольких объединений).

Рассмотрим модели, подобные следующим:

class A(models.Model):
    text = models.CharField(max_length=10, blank=True)

class B(models.Model):
    a = models.ForeignKey(A, null=True, on_delete=models.CASCADE)
    y = models.PositiveIntegerField(null=True)

Теперь я могу использовать функцию values ​​() , подобную этой

B.objects.values('y', 'a__text')

, чтобы получить кортежи, содержащие указанные значения из модели B и фактическое полеот модели A.Если я использую только

B.objects.values()

, я получаю только кортежи, содержащие поля из модели B (т. Е. y и идентификатор внешнего ключа a).Давайте предположим сценарий, в котором B и A имеют много полей, и меня интересуют все те, которые принадлежат B, но только в одном поле из A. Вручную указав все имена полей в values()вызов был бы возможен, но утомителен и подвержен ошибкам.

Так есть ли способ указать, что я хочу все локальные поля, но только (несколько) конкретных объединенных полей (полей)?

Примечание. В настоящее время я использую Django 1.11, но если решение работает только с более свежей версией, меня это тоже интересует.

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Может быть, что-то подобное будет работать в вашем случае?

B.objects.select_related('a').defer('a__field_to_lazy_load');

Это загрузит все поля из обеих моделей, кроме тех, которые вы указали в defer (), где вы можете использовать обычное соглашение о двойном подчеркивании Djangoпроследить отношения.

Поля, указанные вами в defer (), не будут загружены из БД, но будут, если вы попытаетесь получить к ним доступ позже (например, в шаблоне).

0 голосов
/ 05 октября 2018

Вы можете использовать prefetch_related для этого.См. документы :

Вы хотите использовать методы оптимизации производительности, такие как отложенные поля:

queryset = Pizza.objects.only ('name')

restaurant = Restaurant.objects.prefetch_related (Prefetch ('best_pizza', queryset = queryset))

В вашем случае вы можете сделать что-то вроде этого:

from django.db.models import Prefetch

queryset = A.objects.only('text')
b_list = B.objects.prefetch_related(Prefetch('a', queryset=queryset))
...