【问题标题】:Bootstrap navbar dropdown populated with database entries in Django 2使用 Django 2 中的数据库条目填充的引导导航栏下拉列表
【发布时间】:2018-12-19 03:47:05
【问题描述】:

我正在尝试使用从 sqlite3 数据库中的数据填充的单个“下拉项”填充导航栏“下拉菜单”。

我在其他页面上有类似的工作,但我无法让它在我的导航栏中工作。

我正在创建一个唱片公司,并希望从数据库中的条目中填充艺术家列表。我找到了一个关于在 php 中做类似事情的教程,但没有翻译,而且除了填充表单数据之外,youtube 或这里似乎没有任何内容。

非常感谢任何帮助,因为我已经尝试让它工作大约一周了。我知道它应该很简单,但我错过了一些东西。

应用程序被称为“音乐”

models.py

class Artist(models.Model):
    artist_name = models.CharField(max_length=250, default='')
    artist_logo = models.FileField()
    artist_url = models.URLField(blank=True)

    def __str__(self):
        return self.artist_name

class Release(models.Model):
    artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
    release_title = models.CharField(max_length=500)
    release_cover = models.FileField()
    release_duration = models.IntegerField()

    def __str__(self):
        return self.release_title

class Track(models.Model):
    release = models.ForeignKey(Release, default='', on_delete=models.CASCADE)
    artist = models.ForeignKey(Artist, default='', on_delete=models.CASCADE)
    track_title = models.CharField(max_length=200)
    track_version = models.CharField(max_length=200)
    track_genre = models.CharField(max_length=100)
    track_duration = models.IntegerField()
    track_number = models.SmallIntegerField()

    class Meta:
        ordering = ["track_number"]

    def __str__(self):
        return self.track_title

views.py

from django.contrib.auth import authenticate, login
from django.views import generic
from django.views.generic import ListView, View
from .models import Artist, Track, Release
from .forms import UserForm

# class IndexView(ListView):
#     template_name = 'music/index.html'

class ReleaseView(generic.ListView):
    template_name = 'music/releaselist.html'
    context_object_name = 'all_releases'

    def get_queryset(self):
        return Release.objects.all()

class ArtistView(generic.ListView):
    model = Artist
    template_name = 'music/artistlist.html'
    context_object_name = 'all_artists'

    def get_queryset(self):
        return Artist.objects.all()

class DetailView(generic.DetailView):
    model = Release
    template_name = 'music/detail.html'

urls.py(主要)

from django.contrib import admin
from django.urls import path, include, re_path
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
# include urls from the music app
    path('music/', include('music.urls'))

urls.py(“音乐”,也就是应用程序的 url)

from django.contrib import admin
from django.urls import path, include, re_path
from . import views

# defined the app name in case the same fields are used in other apps
app_name = 'music'

urlpatterns = [
    # no info past music return index EG /music/
    # path('', views.IndexView.as_view(), name='index'),
    # albums/releases
    re_path(r'^release/$', views.ReleaseView.as_view(), name='release'),
    # looking for music page with album id afterwards /music/1
    re_path(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name="detail"),
    re_path(r'^(?P<pk>[0-9]+)/$', views.ArtistView.as_view(), name="artist"),

base.html

      <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
          Artists
        </a>
        <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
            {% for artist in all_artists %}
                <li><a class="dropdown-item" href="#">{{ artist.artist_id }}</a></li>
            {% endfor %}
        </div>

      </li>

更新: 这是我的releases.html,它使用类似的代码,底部有一个看起来for循环不正确的测试

{% extends 'music/base.html' %}
{% block title %}KOLD FUZEON: Releases{% endblock %}

{% block body %}

        {% if all_releases %}
            <ul>
                {% for release in all_releases %}
                    <div class="releaseitem">
                        <li><a href="{% url 'music:detail' release.id %}">{{ release.artist }} - {{ release.release_title }}</a></li>
                        <li><a href="{% url 'music:detail' release.id %}"</a><img src="{{ release.release_cover.url }}" style="width: 300px"></li>
                    </div>
                {% endfor %}
            </ul>
        {% else %}
            <h3>We currently dont have any releases yet.</h3>
        {% endif %}


{#basic test for the artist list to be printed to screen#}
            <ul>
                <li>test1</li>
                {% for artist in all_artists %}
                    <li>test2</li>
                {% endfor %}
            </ul>



{% endblock %}

【问题讨论】:

  • 在您的模板 base.html 中,尝试使用 {{artist.artist_name}} 而不是 {{ artist.artist_id }}
  • 感谢您的回复。我已经尝试过了,它仍然是一样的。我尝试用纯文本放入测试列表项,它在 for 循环内不起作用,但在 for 循环外起作用。
  • 兄弟,让我处理你的代码。给我一些时间。

标签: django drop-down-menu sqlite navbar


【解决方案1】:

在您的 View.py 中,您有 ArtistView 其中 模板artistlist.html 并且您的上下文是 all_artist 并且您从 db 中获取所有对象。

代码:

class ArtistView(generic.ListView):
model = Artist
template_name = 'music/artistlist.html'
context_object_name = 'all_artists'

def get_queryset(self):
    return Artist.objects.all()

现在我相信你有一个名为artistlist.html 的模板。如果不在templates 中创建它,您将在其中使用 for 循环 渲染艺术家列表,所以artistlist.html的代码应该是这样的:

{% extends 'music/base.html' %}
{% block body %}

   <h1>Artists!</h1>

<ul>
{% for artist in all_artists %}
  <li class="artist">
     <h1>
         <a href='/music/{{ artist.id }}'>{{artist.artist_name }}</a>  
     </h1>
  </li>
{% endfor %}
</ul>

</div>

{% endblock %}

您可以在Base.html中渲染艺术家列表。 使用:Context Processor

首先在您的App 中创建一个名为context_processors.py 的文件。然后在该文件中添加此代码。

from .models import Artist

def basetest(request):

    hello = Artist.objects.values_list("artist_name", flat=True)
    return {
        'testname': hello
    }

之后,打开Settings.py,找到context_processors,添加如下设置'yourapp.context_processors.add_variable_to_context'

Settings.py

TEMPLATES = [
{
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [],
    'APP_DIRS': True,
    'OPTIONS': {
        'context_processors': [
            'django.template.context_processors.debug',
            'django.template.context_processors.request',
            'django.contrib.auth.context_processors.auth',

            #This one is from my code so set it according to you
            #appname.context_processors.function_name_context_processor.py',

            'blog.context_processors.basetest',

        ],
    },
},
]

在此之后,只需根据您的需要将 {{ testname }} 放入您的base.html。它会起作用的。无需循环,只需插值即可为您呈现一个列表。遵循此 doc

,根据您的需要对其进行格式化

【讨论】:

  • @DesCahill,我已更新代码以在您的base.html 中呈现模型数据。
  • @DesCahill 问题末尾提供的链接是为了让您了解如何格式化数据并创建链接,我已经为此更新了我的答案。答案解决了您在base.html 上渲染数据的主要查询。
  • @DesCahill,通过接受答案来帮助我,因为它解决了您的主要问题。
  • 感谢您的赞赏。
  • 工作就像一个魅力。给大家小费。上述解决方案适用于那些希望在整个网站的某个地方始终提供一些数据的人。例如:导航栏下拉列表。否则,您将必须始终从所有视图传递查询结果。感谢安舒曼。超级解决方案。
【解决方案2】:

我认为您在上下文中传递的“键”的名称存在问题。

在 ReleaseView 中,上下文对象名称是 all_releases,而您正在尝试迭代“all_artists”。

即使这些更改不起作用,您也可以随时尝试在普通视图而不是通用视图上运行代码,并在模板中传递上下文。

【讨论】:

  • 再次查看问题。他有一个ArtistView
  • 非常感谢您的回复。我刚刚尝试通过打印出两个测试列表项来简化它。 “test1”出现了,但“test2”没有出现,这看起来像是我的“for循环”的问题,但我不确定问题是什么。 code
    • test1
    • {% for artist in all_artists %}
    • test2
    • {% endfor %}
    code
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-04
  • 1970-01-01
  • 2020-06-23
  • 1970-01-01
  • 2016-05-15
相关资源
最近更新 更多