【问题标题】:For loop only working in one template in djangoFor循环仅在django中的一个模板中工作
【发布时间】:2023-03-09 13:35:01
【问题描述】:

我正在尝试建立一个教育网站,并尝试将所有使用 for 循环的类别放在导航栏中的下拉列表中。我已将它放在 base.html 中,所有其他模板都扩展了 base.html。但是项目只显示在模板为home.html的根页面中。

我尝试过将多个上下文传递给所有帖子。

base.html:

{% load static %}
<!doctype html>
<html>
<head>
     <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

    <link rel="stylesheet" type="text/css" href="{% static 'blog/main.css' %}">


        <title>{% block title %}ION{% endblock %}</title>
</head>
<body>
    <header class="site-header">
      <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
        <div class="container">
          <a class="navbar-brand mr-4" href="{% url 'blog-home' %}">ION</a>
          <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarToggle" aria-controls="navbarToggle" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
          </button>
          <div class="collapse navbar-collapse" id="navbarToggle">
            <div class="navbar-nav mr-auto">
              <a class="nav-item nav-link" href="{% url 'blog-home' %}">Home</a>
              <a class="nav-item nav-link" href="{% url 'post-all' %}">Posts</a>
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Categories</a>
                        <div class="dropdown-menu" aria-labelledby="navbarDropdown">
                          {% for cate in cat %}
                              <a class="dropdown-item" href="{% url 'category' cate.pk %}">{{ cate.name }}</a>
                          {% endfor %}
                        </div>
                    </li>
              <a class="nav-item nav-link" href="{% url 'blog-about' %}">About</a>
            </div>
            <!-- Navbar Right Side -->
            <div class="navbar-nav">
                {% if user.is_authenticated %}
                    <a class="nav-item nav-link" href="{% url 'post-create' %}">New Post</a>
                    <a class="nav-item nav-link" href="{% url 'profile' %}">Profile</a>
                    <a class="nav-item nav-link" href="{% url 'logout' %}">Logout</a>
                {% else %}
                    <a class="nav-item nav-link" href="{% url 'login' %}">Login</a>
                    <a class="nav-item nav-link" href="{% url 'register' %}">Register</a>
                {% endif %}
            </div>
          </div>
        </div>
      </nav>
    </header>
    <main role="main" class="container">
      <div class="row">
        <div class="col-md-12">
            {% if messages %}
                {% for message in messages %}
                    <div class="alert alert-{{message.tags}}">
                        {{message}}
                    </div>
                {% endfor %}
            {% endif %}
            {% block content %}{% endblock %}
        </div>
        </div>
      </div>
    </main>
        <!-- Optional JavaScript -->
    <!-- jQuery first, then Popper.js, then Bootstrap JS -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
<!--From snippets navigation, main, and the starter template: https://getbootstrap.com/docs/4.3/getting-started/introduction/

home.html(仅在其工作的地方):

{% extends "blog/base.html" %}
{% block title %}
ION Home
{% endblock %}
{% block content %}
    <div class="text-center">
        <h1>Home</h1>
    </div>
    <div class="card">
        <img class="card-img-top" src="https://www.litmos.com/wp-content/uploads/2016/06/blog-eLearning-templates.png" alt="Card image cap">
        <div class="card-body">
            <h3 class="card-title text-center">Learning Reimagined</h3>
            <p class="card-text">
                ION is an open network that intends to reimagine learning. Anyone from anywhere can upload courses and help those unable to go to conventional schools or as an aid for education.
                We promote education to the fullest. We believe in equal right for everyone. Students can take the help of ION to study or even make ION their primary study source.
            </p>
        </div>
    </div>

{% endblock %}


views.py:



def home(request):
    context = {
    'posts': Post.objects.all(),
    'cat': Category.objects.all()
    }

    return render(request, 'blog/home.html', context)


def about(request):
    return render(request, 'blog/about.html', {'title':'About'})


class PostListView(ListView):
    model = Post
    template_name = 'blog/posts.html' #<app>/<model>_<viewtype>.html
    context_object_name = 'posts'        #It needs the specifying to loop over just like it did in the context of home
    ordering = ['-date_posted']
    paginate_by = 15


class UserPostListView(ListView):
    model = Post
    template_name = 'blog/user_posts.html' #This is when you click a profile in a post, it takes you to his posts only
    context_object_name = 'posts'
    paginate_by = 15

    def get_queryset(self):#This does so that it takes you to the user posts only if he currently still exists
        user = get_object_or_404(User, username=self.kwargs.get('username'))
        return Post.objects.filter(author=user).order_by('-date_posted')


class PostDetailView(DetailView):
    model = Post


class PostCreateView(LoginRequiredMixin, CreateView):
    model = Post
    fields = ['title', 'content', 'display', 'category']

    def form_valid(self, form):#This sets the user to be the author of the  blog you're trying to create
        form.instance.author = self.request.user
        return super().form_valid(form)


class PostUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
    model = Post
    fields = ['title', 'content', 'display', 'category']

    def form_valid(self, form):
        form.instance.author = self.request.user
        return super().form_valid(form)

    def test_func(self):#This is where only the author can update the post
        post = self.get_object()
        if self.request.user == post.author:
            return True
        return False


class PostDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
    model = Post
    success_url = '/'
    def test_func(self):#This is where only the author can update the post
        post = self.get_object()
        if self.request.user == post.author:
            return True
        return False


class CatPostListView(ListView):
    model = Post
    template_name = 'blog/science.html' #This is when you click a profile in a post, it takes you to his posts only
    context_object_name = 'posts'
    paginate_by = 15

    def get_queryset(self):
        return Post.objects.filter(category=2).order_by('-date_posted')

models.py:

class Category(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField()
    parent = models.ForeignKey('self', blank=True, null=True, related_name='children', on_delete=models.SET_NULL)

    class Meta:
        # enforcing that there can not be two categories under a parent with same slug

        # __str__ method elaborated later in post.  use __unicode__ in place of

        # __str__ if you are using python 2

        unique_together = ('slug', 'parent',)
        verbose_name_plural = "categories"


    def __str__(self):
        return self.name

class Post(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    category = models.ForeignKey('Category', null=True, blank=True, on_delete=models.SET_NULL)
    display = models.TextField(max_length=250)
    date_posted = models.DateTimeField(default=timezone.now)#DON'T USE () HERE Just auto_now_ will show the date of the current day
    author = models.ForeignKey(User, on_delete=models.CASCADE)#No () #This deletes the posts when the user is deleted


    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse('post-detail', kwargs={'pk': self.pk})

我希望类别显示在所有页面上。

【问题讨论】:

  • 我不知道你为什么会这样,因为你只是在home view 中发送它们。如果您希望它们出现在每个页面上,请使用上下文处理器或自定义模板标签。

标签: django python-3.x


【解决方案1】:

不会,因为其他页面(除了首页)没有分类数据。因此,您可以在每个视图中通过上下文变量cat 发送类别变量,也可以创建一个custom context processor,如下所示:

def cat_on_all_pages(request):
    return {'cat': Category.objects.all()}

并在设置中添加:

'OPTIONS': {
        'context_processors': [
            'path.to.cat_on_all_pages',
            # other context processors
        ],
     }

如果添加自定义上下文处理器,则可以从主视图的上下文中删除 cat

【讨论】:

  • 这看起来很有希望,但它对我不起作用,可能是因为我正在尝试获得一组用户。 (我想要一个基本上是一个用户组列表的菜单。)我的代码看起来和你的差不多:def attorney_menu_on_all_pages(request): return { 'attorneys': User.objects.filter(groups__name='attorney-staff') } ...但我收到错误name 'User' is not defined。 User 是否与 Category 不同,因为它是默认模型或其他什么?
  • 哦,不,这是因为我在 context_processors.py 中省略了 from .models import User
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-17
  • 2013-10-26
  • 1970-01-01
  • 2012-01-02
  • 1970-01-01
  • 2018-05-25
  • 2015-03-21
相关资源
最近更新 更多