Запрос 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 %}
Вернуться на верх