как быстро выбирать поля в связанных таблицах в моделях django

#django #python-3.x #django-models

#django #python-3.x #django-модели

Вопрос:

Я пытаюсь получить все значения в текущей таблице, а также получить некоторые поля в связанных таблицах.

 class school(models.Model):
    school_name = models.CharField(max_length=256)
    school_type = models.CharField(max_length=128)
    school_address = models.CharField(max_length=256)

class hometown(models.Model):
    hometown_name = models.CharField(max_length=32)

class person(models.Model):
    person_name = models.CharField(max_length=128)
    person_id = models.CharField(max_length=128)
    person_school = models.ForeignKey(school, on_delete=models.CASCADE)
    person_ht = models.ForeignKey(hometown, on_delete=models.CASCADE)
  

как быстро выбрать всю необходимую мне информацию в dict для рендеринга.
будет много записей лично, я получил ввод school_id и хочу получить всех пользователей в этой школе, а также хочу, чтобы отображалось их hometown_name.

я пробовал так, могу получить нужную информацию. И любой другой быстрый способ сделать это?

 m=person.objects.filter(person_school_id=1)
.values('id', 'person_name', 'person_id', 
school_name=F('person_school__school_name'), 
school_address=F('person_school__school_address'), 
hometown_name=F('person_ht__hometown_name'))
  

person_name, person_id, school_name, school_address, hometown_name

если у человека много полей, перечислить все значения будет непросто.

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

 m=person.objects.filter(person_school_id=1).XXXX.values()
  

он может отображать все значения в школе и все значения в родном городе вместе со значениями person в m, и я могу

 for x in m: 
   print(x.school_name, x.hometown_name, x.person_name)
  

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

1. select_related , prefetch_related .

2. можете ли вы привести мне пример? Спасибо

Ответ №1:

Вы добавляете prefetch_related запрос поверх своего набора запросов.

prefetch_data = Prefetch('person_set, hometown_set, school_set', queryset=m)

Where prefetch_data подготовит вашу базу данных для извлечения связанных таблиц и m является вашим исходным отфильтрованным запросом (поэтому добавьте это под своим Person.objects.filter(... )

Затем вы выполняете фактический запрос к БД:

query = query.prefetch_related(prefetch_data)

Где query будет фактическим результирующим запросом со списком Person объектов (поэтому добавьте эту строку ниже prefetch_data одной).

Пример:

 m=person.objects.filter(person_school_id=1)
.values('id', 'person_name', 'person_id', 
school_name=F('person_school__school_name'), 
school_address=F('person_school__school_address'), 
hometown_name=F('person_ht__hometown_name'))

prefetch_data = Prefetch('person_set, hometown_set, school_set', queryset=m)

query = query.prefetch_related(prefetch_data)
  

В этом примере я разбил запросы на более управляемые части, но вы также можете сделать все это в одной большой строке (хотя и менее управляемой для чтения):

 m=person.objects.filter(person_school_id=1)
.values('id', 'person_name', 'person_id', 
school_name=F('person_school__school_name'), 
school_address=F('person_school__school_address'), 
hometown_name=F('person_ht__hometown_name')).prefetch_related('person, hometown, school')
  

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

1. что я имею в виду, есть ли какой-либо набор запросов, который может объединять поля связанных таблиц вместе, которым не нужно указывать поля в значениях. Может быть, так: m=person.objects.filter(person_school_id=1).values().XXXX он может отображать все значения в школе и все значения в родном городе вместе со значениями person в m, и я могу «для x в m: print (x.school_name)»