Я пытаюсь создать образовательный сайт и пытаюсь поместить все категории, использующие циклы 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})
Iожидать, что категории будут отображаться на всех страницах.