Запрос Django с 3 таблицами
Я надеюсь, что смогу получить небольшое руководство.
Я пытаюсь вернуть данные из 3 связанных таблиц в моем шаблоне. В SQL это простой подход, но требования Django заставляют меня споткнуться.
Я хотел бы отображать информацию, подобную этой:
WaiverAdult.first_name CheckIn.checkintime
WaiverMinor.first_name CheckIn.checkintime
WaiverAdult.first_name CheckIn.checkintime
WaiverMinor.first_name CheckIn.checkintime
WaiverMinor.first_name CheckIn.checkintime
Вот упрощенное представление моделей с определенными отношениями.
class WaiverAdult(models.Model):
first_name = models.CharField(max_length=50, blank=True)
class WaiverMinor(models.Model):
first_name = models.CharField(max_length=50, blank=True)
parent = models.ForeignKey(WaiverAdult, on_delete=models.CASCADE)
class CheckIns(models.Model):
adult = models.ForeignKey(WaiverParent, on_delete=models.CASCADE, blank=True, null=True)
minor = models.ForeignKey(WaiverChild, on_delete=models.CASCADE, blank=True, null=True)
checkintime = models.DateTimeField(auto_now_add=True)
Вот мой упрощенный взгляд:
class WaiverListView(ListView):
waiver_adults = WaiverAdult.objects.all().prefetch_related(
'waiverminor_set').order_by('created')
queryset = waiver_adults
context_object_name = "waiver_list"
template_name = 'waiver/waiver_list.html'
А это мой шаблон.
{% for adult in waiver_list %}
<tr>
<td>{{adult.first_name}}</td>
<td>insert the adult checkin time here</td>
</tr>
{% for child in adult.waiverminor_set.all %}
<tr>
<td>{{child.first_name}}</td>
<td>insert the child checkin time here</td>
</tr>
{% endfor %}
{% endfor %}
Я был бы очень признателен за подробности в объяснениях, так как я действительно хочу понять, как все это работает.
Заранее спасибо.
Во-первых, для каждого иностранного ключа, который вы создаете, я предлагаю вам добавить related_name
таким образом, вы указываете имя обратного отношения между дочерней моделью и родительской моделью, в вашем случае, например, ваш код должен быть:
class WaiverAdult(models.Model):
first_name = models.CharField(max_length=50, blank=True)
class WaiverMinor(models.Model):
first_name = models.CharField(max_length=50, blank=True)
parent = models.ForeignKey(WaiverAdult, on_delete=models.CASCADE,related_name='minor_of_adult')
и давайте объясним, как это работает, вы хотите узнать и получить всех несовершеннолетних некоторого взрослого, что вы должны сделать, это указать взрослого, и получить всех несовершеннолетних, связанных с этим взрослым, в контексте кода (попробуйте это в оболочке django, используя python manage.py shell
):
adult = WaiverAdult.objects.get(first_name='cbirch') //specifying the adult
adult.minor_of_adult.all() //notice how we access the minor using the related_name
То же самое относится к последней модели CheckIns
.
В созданных вами моделях возможно несколько раз регистрировать родителя и ребенка, поэтому вам нужно просмотреть список в цикле. Также ваши внешние ключи ссылаются на WaiverParent и WaiverChild, в то время как фактические имена моделей - WaiverAdult и WaiverMinor. Вы можете попробовать следующий шаблон:
{% for adult in waiver_list %}
<tr>
<td>{{adult.first_name}}</td>
<td>
{% for checkin in adult.checkins_set.all %}
{{ checkin.checkintime }}
{% endfor %}
</td>
</tr>
{% for child in adult.waiverminor_set.all %}
<tr>
<td>{{child.first_name}}</td>
<td>
{% for checkin in child.parent.checkins_set.all %}
{{ checkin.checkintime }}
{% endfor %}
</td>
</tr>
{% endfor %}
{% endfor %}