Django for loop работает на одной странице шаблона, но исчезает в других местах?

Я написал цикл Django for, который итерирует каждый экземпляр моей модели Supplier для отображения каждого экземпляра в навигационной панели. Однако по какой-то причине он выводится только на одном из моих шаблонов, а не на главной странице. Вот цикл, о котором идет речь:

<ul class="nav-drop">
    {% for supplier in suppliers %}
    <li>
        <a href="{% url 'supplier' pk=supplier.pk %}">{{ supplier.name }}</a>
    </li>
    {% endfor %}
</ul>

вот мой файл views.py:

from django.shortcuts import render
from . models import Supplier

# Create your views here.
def suppliers(request):
    suppliers = Supplier.objects.all()

    context = {'suppliers': suppliers}
    return render(request, 'suppliers/suppliers.html', context)

def supplier(request, pk):
    supplier = Supplier.objects.get(id=pk)

    context = {'supplier': supplier}
    return render(request, 'suppliers/supplier.html', context)
from django.urls import path
from . import views

urlpatterns = [
    path('suppliers/', views.suppliers, name='suppliers'),
    path('supplier/<str:pk>/', views.supplier, name='supplier')
]

и рассматриваемая модель:

class Supplier(models.Model):
    name = models.CharField(max_length=200, blank=True, null=True)
    logo_image = models.ImageField(null=True, blank=True, upload_to='models/',
    default="models/default.jpg") 
    marketing_image = models.ImageField(null=True, blank=True, upload_to='models/', 
    default="models/default.jpg")
    description = models.TextField(blank=True, null=True)
    short_description = models.TextField(max_length=200, blank=True, null=True)
    social_facebook = models.CharField(max_length=200, blank=True, null=True)
    social_twitter = models.CharField(max_length=200, blank=True, null=True)
    social_instagram = models.CharField(max_length=200, blank=True, null=True)
    social_youtube = models.CharField(max_length=200, blank=True, null=True)
    social_linkedin = models.CharField(max_length=200, blank=True, null=True)
    social_website = models.CharField(max_length=200, blank=True, null=True)
    created = models.DateTimeField(auto_now_add=True)
    id = models.UUIDField(default=uuid.uuid4, unique=True,
                          primary_key=True, editable=False)

Я пытался часами, но, к сожалению, не смог найти решение

Похоже, что вы передаете список поставщиков только в одном из ваших представлений. Поэтому в одном из них есть что отображать, а в другом нет, основным решением будет добавление поставщиков в контекст всех ваших представлений.

# Create your views here.
def suppliers(request):
    suppliers = Supplier.objects.all()

    context = {'suppliers': suppliers}
    return render(request, 'suppliers/suppliers.html', context)

def supplier(request, pk):
    suppliers = Supplier.objects.all()
    supplier = Supplier.objects.get(id=pk)

    context = {'supplier': supplier, 'suppliers': suppliers}
    return render(request, 'suppliers/supplier.html', context)

Как вы можете видеть, это противоречит принципу DRY, делая ваш код грязным. Одним из возможных решений является представление для отправки AJAX из вашего base.html (где вы, вероятно, включили навигационную панель):

base.html

<!DOCTYPE html>
<html>
    <head>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
    </head>
    <header>
        {% include 'includes/navbar.html' %}
    </header>
    <body>
        {% block content%}
        
        {% endblock content%}
    </body>
    <footer>
        <script>
            fetch("{% url 'core:supplier_list_ajax' %}")
            .then((response) => response.json())
            .then((data) => {
                let e = document.getElementById("second-choice");
                for (let key in data['suppliers']){
                    id = data['suppliers'][key].id
                    name = data['suppliers'][key].name
                    url = `/supplier/${id}/`
                    e.innerHTML += `<a href="${url}">${name}</a><br>`
                }
            });
        </script>
    </footer>
</html>

navbar.html

<div class="dropdown">
    <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
      Normal Dropdown
    </button>
    <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
        {% for supplier in suppliers %}
        <li>
            <a href="{% url 'core:supplier' pk=supplier.pk %}">{{ supplier.name }}</a>
        </li>
        {% endfor %}
    </ul>

    <button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton1" data-bs-toggle="dropdown" aria-expanded="false">
      AJAX Dropdown
    </button>
    <ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
      <li id="second-choice">
      </li>
    </ul>
  </div>

views.py

from django.shortcuts import render
from django.http import JsonResponse

from .models import Supplier

def suppliers(request):
    suppliers = Supplier.objects.all()

    context = {'suppliers': suppliers}
    return render(request, 'suppliers/suppliers.html', context)

def supplier(request, pk):
    supplier = Supplier.objects.get(id=pk)

    context = {'supplier': supplier}
    return render(request, 'suppliers/supplier.html', context)

def supplier_list_ajax(request):
    suppliers = list(Supplier.objects.all().values('name','id'))
    return JsonResponse({'suppliers': suppliers})

urls.py

from django.urls import path
from core import views

app_name = 'core'

urlpatterns = [
    path('suppliers/', views.suppliers, name='suppliers'),
    path('supplier/<str:pk>/', views.supplier, name='supplier'),
    path('supplier/list/ajax/', views.supplier_list_ajax, name='supplier_list_ajax')
]

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

Вернуться на верх