Как вывести несколько значений из двух списков в шаблоне django

Я пытаюсь найти способ вывести значения из двух различных контекстных переменных в одном цикле. Я пробовал метод zip() , но он, похоже, не работает и не выводит переменные на шаблон.

Вот как я пытался

index.html

<tbody>
                {% for item1, item2 in mylist %}
                <tr>
                  <td><a href="/{{ url.short_url }}">/{{ item1.short_url }}</a></td>
                  <td>{{ item1.original_url }}</td>
                  <td>{{ item1.created_at }}</td>
                  <td>{{ item1.clicks|intcomma }}</td>
                  <td>{{ item2.browser }}</td>
                  <td>{{ item2.platform }}</td>
                  <td><a href="#">
                      <svg class="octicon octicon-graph" viewBox="0 0 16 16" version="1.1" width="16" height="16"
                        aria-hidden="true">
                        <path fill-rule="evenodd" d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z">
                        </path>
                      </svg>
                    </a></td>
                </tr>
                {% endfor %}
              </tbody>

views.py

def index(request):
    urls = Url.objects.order_by('-created_at')
    clicks = Click.objects.order_by('-created_at')
    # context = {'urls': urls, 'clicks': clicks}
    mylist = zip(urls, clicks)
    context = {
                'mylist': mylist,
            }
    return render(request, 'heyurl/index.html', context)

Но при запуске локального сервера я ничего не вижу в представлении таблицы.

Что я делаю не так? Есть ли какие-нибудь альтернативы?

Вот моя текущая версия кода.

models.py

from django.db import models

class Url(models.Model):
    short_url = models.CharField(max_length=255)
    original_url = models.CharField(max_length=255)
    clicks = models.IntegerField(default=0)
    created_at = models.DateTimeField('date created', auto_now_add=True)
    updated_at = models.DateTimeField('date updated', auto_now=True)

class Click(models.Model):
    url = models.ForeignKey(Url, on_delete=models.CASCADE, related_name='related_clicks')
    browser = models.CharField(max_length=255)
    platform = models.CharField(max_length=255)
    created_at = models.DateTimeField('date created', auto_now_add=True)
    updated_at = models.DateTimeField('date updated', auto_now=True)

index.py

def index(request):
    urls = Url.objects.order_by('-created_at')
    clicks = Click.objects.order_by('-created_at')
    context = {'urls': urls, 'clicks': clicks}
    return render(request, 'heyurl/index.html', context)

templates/index.html

                <tbody>
                {% for url in urls %}
                <tr>
                  <td><a href="/{{ url.short_url }}">/{{ url.short_url }}</a></td>
                  <td>{{ url.original_url }}</td>
                  <td>{{ url.created_at }}</td>
                  <td>{{ url.clicks|intcomma }}</td>
                  <td>{{ click.browser }}</td>
                  <td>{{ click.platform }}</td>
                  <td><a href="#">
                      <svg class="octicon octicon-graph" viewBox="0 0 16 16" version="1.1" width="16" height="16"
                        aria-hidden="true">
                        <path fill-rule="evenodd" d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z">
                        </path>
                      </svg>
                    </a></td>
                </tr>
                {% endfor %}
              </tbody>

В views.py :

попробуйте использовать map вместо zip, особенно если два списка имеют разную длину

mylist = map(None, urls, clicks)

в views.py

def index(request):
    urls = Url.objects.order_by('-created_at')
    clicks = Click.objects.order_by('-created_at')
    mylist = zip(urls, clicks)  # this should be fine but if it doesn't work try mylist= map(None, urls, clicks)
    context = {
                'mylist': mylist,
            }
    return render(request, 'heyurl/index.html', context)

в template/index.html

                <tbody>
                {% for url, click in mylist %}
                <tr>
                  <td><a href="/{{ url.short_url }}">/{{ url.short_url }}</a></td>
                  <td>{{ url.original_url }}</td>
                  <td>{{ url.created_at }}</td>
                  <td>{{ url.clicks|intcomma }}</td>
                  <td>{{ click.browser }}</td>
                  <td>{{ click.platform }}</td>
                  <td><a href="#">
                      <svg class="octicon octicon-graph" viewBox="0 0 16 16" version="1.1" width="16" height="16"
                        aria-hidden="true">
                        <path fill-rule="evenodd" d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z">
                        </path>
                      </svg>
                    </a></td>
                </tr>
                {% endfor %}
              </tbody>

Это альтернатива

Просто пройдитесь циклом по объектам Click и дойдите до их пары Url через ForeignKey, Это будет намного проще!

def index(request):
    clicks = Click.objects.all().order_by('-created_at')
    context = {'clicks': clicks}
    return render(request, 'heyurl/index.html', context)
                <tbody>
                {% for i in clicks %}
                <tr>
                  <td><a href="/{{ i.url.short_url }}">/{{ i.url.short_url }}</a></td>
                  <td>{{ i.url.original_url }}</td>
                  <td>{{ i.url.created_at }}</td>
                  <td>{{ i.url.clicks|intcomma }}</td>
                  <td>{{ i.browser }}</td>
                  <td>{{ i.platform }}</td>
                  <td><a href="#">
                      <svg class="octicon octicon-graph" viewBox="0 0 16 16" version="1.1" width="16" height="16"
                        aria-hidden="true">
                        <path fill-rule="evenodd" d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z">
                        </path>
                      </svg>
                    </a></td>
                </tr>
                {% endfor %}
              </tbody>

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

# This is just illustrating the point

# Pairs
Click0 - > Url0,
Click1 - > None,
Click2 - > Url2,
Click3 - > Url3,

## Loop Output
Click0 - > Url0,
Click1 - > Url2, # x    :(
Click2 - > Url3, # x    :(
Click3 - > None, # Actually Click3 might not even show!
Вернуться на верх