Model in header doesn't appear in views that use the header - django

Model defined in the header of my pages appears on page load and refresh on the main page, but when I navigate to another view the model doesn't appear there. The rest of the header is there, just the dynamic data that isn't.
Where am I going wrong? New to both Python and Django, so if anyone can help, please don't be afraid to patronize and Eli5 :)
Model defined in models.py:
from django.db import models
from django.utils import timezone
# Create your models here.
class Propaganda(models.Model):
slogan = models.CharField(max_length=140, blank=True, null=True)
def __str__(self):
return self.slogan
header.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Christopher's weblog</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Blog site.">
<!-- Let's get the static files where we use them, but this could be before the html tag -->
{% load staticfiles %}
<link rel="stylesheet" href="{% static 'blog/css/bulma.css' %}" type="text/css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- <link rel="stylesheet" href="{% static 'blog/css/cupar.css' %}" type="text/css" /> -->
</head>
<body>
<section class="hero is-success is-bold">
<div class="hero-body">
<div class="container">
{% block slogan %}
{% for propaganda in propagandas %}
<h6>{{ propaganda.slogan }} it's</h6>
{% endfor %}
{% endblock %}
<h1 class="title" style="display: inline-block;">
<span class="icon">
<i class="fa fa-home"></i>
</span>
The Guide
</h1>
{% if user.is_authenticated %}
<div class="field">
<div class="control">
<a href="{% url 'post_new' %}" class="button is-warning is-pulled-right">
<span class="icon">
<i class="fa fa-plus-square"></i>
</span>
<span>New post</span>
</a>
</div>
</div>
{% endif %}
</div><!-- #container -->
</div>
</section>
<!-- content under header in here-> -->
{% block content %}
{% endblock %}
</body>
</html>
views.py
from django.template import RequestContext
from django.shortcuts import render, get_object_or_404, redirect
from .models import Post, Propaganda
from .forms import PostForm
from django.utils import timezone
# Create your views here.
def post_list(request):
posts = Post.objects.all()
propagandas = Propaganda.objects.all().order_by('?')[:1]
return render(request, 'blog/post_list.html', {'posts': posts, 'propagandas': propagandas})
post_detail.html (where the model does not appear):
{% extends 'blog/header.html' %}
{% block content %}
some html / form that has nothing to do with the header.
{% endblock %}
post_list.html (the 'index' page where the model works fine)
{% extends "blog/header.html" %}
{% block content %}
{% for post in posts %}
<section class="section">
more html
{% endblock %}

need to pass the data from each view function that is required in the header you are extending (re-using) in each template.
def post_detil(request, id):
posts = Post.objects.all()
propagandas = Propaganda.objects.all().order_by('?')[:1]
# ... add in other stuff relevant to post details ...
post = Post.objects.get(pk=id)
return render(request, 'blog/post_detail.html', {'posts': posts, 'propagandas': propagandas, 'post': post})
Stick with it #Rin and Len, you'll get there :)

First: Why are you not showing the view of post_detail. Isn't that the one that does not work?
Second: Even though you are extending a base template you still have to pass the appropriate context in order to generate the desired dynamic data.
I hope it helps.

Related

Django Breadcrumb error: Reverse for 'projectnotes_list' with no arguments not found

I am trying to use django-views-breadcrumbs to add breadcrumbs to a site. I can get it to work with some views but I am getting an error with a particular listview. When I attempt to visit this listview page I see the error.
The error appears to be related to a need for the correct context. So far I have not been able to figure this out.
The error:
NoReverseMatch at /projects/project/1/notes/
Reverse for 'projectnotes_list' with no arguments not found. 1 pattern(s) tried: ['projects/project/(?P<pk>[0-9]+)/notes/\\Z']
Request Method: GET
Request URL: http://co1.localhost:8000/projects/project/1/notes/
Django Version: 3.1.14
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'projectnotes_list' with no arguments not found. 1 pattern(s) tried: ['projects/project/(?P<pk>[0-9]+)/notes/\\Z']
Exception Location: /Users/user/.local/share/virtualenvs/osite-wGphEfbP/lib/python3.9/site-packages/django/urls/resolvers.py, line 689, in _reverse_with_prefix
Python Executable: /Users/user/.local/share/virtualenvs/osite-wGphEfbP/bin/python
Python Version: 3.9.6
Python Path:
['/Users/user/Desktop/otools',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python39.zip',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9',
'/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload',
'/Users/user/.local/share/virtualenvs/osite-wGphEfbP/lib/python3.9/site-packages']
Server time: Sun, 20 Feb 2022 15:52:17 +0000
The list view:
class ProjectNotesList(ListBreadcrumbMixin,ListView):
model = ProjectNotes
template_name = 'company_accounts/project_notes.html'
comments = ProjectNotes.comments
def related_project(self, **kwargs):
project = get_object_or_404(Project, id=self.kwargs.get('pk'))
notes = ProjectNotes.objects.all
return notes
def get_context_data(self, **kwargs):
# Call the base implementation first to get a context
context = super().get_context_data(**kwargs)
context['project'] = get_object_or_404(Project, id=self.kwargs.get('pk'))
return context
commentscount = ProjectNotes.objects.annotate(num_comments=Count('comments'))
The urls.py
from django.urls import path, include
from .views import CompanyProjects, CompanyProjectsDetailView, TodoCreateView, ProjectNotesList, ProjectNotesCreateView, ProjectCreateView, ProjectNotesDetailView, CompanyCompletedProjects, CompanyPausedProjects, TodosList, ProjectTodosDetailView, ProjectDocumentsList, ProjectDocumentsCreateView, ProjectDocumentsDetailView
from . import views
app_name = 'company_project'
urlpatterns = [
path('', CompanyProjects.as_view(), name='project_list'),
path('completed_projects', CompanyCompletedProjects.as_view(), name='completed_projects'),
path('paused_projects', CompanyPausedProjects.as_view(), name='paused_projects'),
path('add_project/', ProjectCreateView.as_view(), name='add_project'),
path('project/<int:pk>/', CompanyProjectsDetailView.as_view(), name='project_detail'),
path('project/<int:pk>/todos/', TodosList.as_view(), name='project_todos'),
path('project/<int:project_pk>/todo/<int:pk>/', ProjectTodosDetailView.as_view(), name='project_todo_detail'),
path('project/<int:pk>/add_todo/', TodoCreateView.as_view(), name='add_todo'),
path('project/<int:pk>/add_project_note/', ProjectNotesCreateView.as_view(), name='add_project_note'),
path('project/<int:pk>/notes/', ProjectNotesList.as_view(), name='projectnotes_list'),
#path('note/<int:pk>/add_project_note_comment/', ProjectNotesCommentCreateView.as_view(),
# name='add_project_note_comment'),
path('project/<int:project_pk>/note/<int:pk>/', ProjectNotesDetailView.as_view(), name='project_note_detail'),
path('project/<int:pk>/documents/', ProjectDocumentsList.as_view(), name='project_documents'),
path('project/<int:pk>/add_project_document/', ProjectDocumentsCreateView.as_view(), name='add_project_document'),
path('project/<int:project_pk>/document/<int:pk>/', ProjectDocumentsDetailView.as_view(), name='project_document_detail'),
]
The base and page templates:
base
<!DOCTYPE html>
{% load static %}
{% load view_breadcrumbs %}
<html>
<head>
<meta charset="utf-8">
<title>{% block title %}Site{% endblock title %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link type="text/x-scss" href="{% static 'bootstrap/scss/bootstrap.scss' %}" rel="stylesheet" media="screen">
<!-- Custom CSS -->
<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}"/>
<link rel="shortcut icon" type="image/png" href="{% static 'core_images/OH_favicon.png' %}"/>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-VJRXH7YFXZ"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-VJRXH7YFXZ');
</script>
</head>
<body>
<wrapper class="d-flex flex-column">
{% include 'nav.html' %}
<main class="flex-fill">
<div class="row">
<div class="col-12">
<br />
{% block breadcrumbs %}
{% render_breadcrumbs 'view_breadcrumbs/bootstrap4.html' %}
{% endblock breadcrumbs %}
{% block messages %}{% endblock messages %}
</div>
</div>
{% block content %}
<h1>Hello</h1>
{% endblock content %}
</main>
{% include 'footer.html' %}
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script
src="https://code.jquery.com/jquery-3.6.0.min.js"
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</wrapper>
</body>
</html>
page
<!-- templates/company_accounts/project_notes.html -->
{% extends 'base.html' %}
{% block content %}
<div class="section-container container">
<div class="general-section-header">
<div class="header-add-new">
<a class="btn btn-success" href="{% url 'company_project:add_project_note' project.pk %}" role="button">Add Note</a>
</div>
<h1>Notes for {{ project }}</h1>
</div>
{% if project.notes.all %}
{% for note in project.notes.all %}
<div class ="projectnotes-entry">
<div class="col-sm-8">
<div class="row-sm-6">
<div class="card mb-2">
<div class="card-body">
<div class="card-title">{{ note.title }}</div>
<div class="card-text">{{ note.body | safe | truncatewords:"20"|linebreaks }}
<div>{{ note.comments.all.count }} comments</div>
read more</div>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
{% else %}
<p>No notes have been have been added yet.</p>
{% endif %}
</div>
{% endblock content %}
There is a demo included with the breadcrumb app the provides some insight. However I have not been able to figure out how to add necessaryt context using code from the demo.
The demo code:
class TestListsView(ListBreadcrumbMixin, ListView):
model = TestModel
template_name = "demo/test-list.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
view_paths = []
for instance in self.object_list:
view_paths.append(
(
instance.name,
detail_instance_view_url(instance),
),
)
context["view_paths"] = view_paths
return context

How to display record one by one using Django template (html) and model

In my code below all the questions & related images stored in my table are coming on same page at one go but I want only first question and its image to appear and than when user clicks on next button the second question along with its image should come, this should repeat till end of records in the table.
View
from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect
from quiz.models import Quiz, Question
def playQuiz(request):
data=Question.objects.filter(__isnull=False)
res=render(request,'quiz/quiz_play.html',{'data':data})
return res
Template
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
{% for data in data %}
<div><h1> {{data.qs}} </h1></div>
<div> <img src="{{ data.qip.url }}" height=300> </div>
<input type="button" name="next-btn" value="NEXT">
{% endfor %}
</body>
</html>
You can use a Paginator to achieve this. It will automatically handle the going forward or backward.
from django.shortcuts import render
from django.core.paginator import Paginator
from quiz.models import Quiz, Question
def playQuiz(request):
data=Question.objects.filter(__isnull=False)
paginator = Paginator(data, 1) # Show 1 data per page.
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
res = render(request, 'quiz/quiz_play.html', {'page_obj': page_obj})
return res
In your template you will use it like this.
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
{% for data in page_obj %}
<div><h1> {{data.qs}} </h1></div>
<div> <img src="{{ data.qip.url }}" height=300> </div>
<input type="button" name="next-btn" value="NEXT">
{% endfor %}
<div class="pagination">
<span class="step-links">
{% if page_obj.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
</span>
{% if page_obj.has_next %}
next
last »
{% endif %}
</span>
</div>
</body>
</html>

Getting NoReverseMatch at /blog/ at the book django by example

The ERROR :
django.urls.exceptions.NoReverseMatch: Reverse for 'post_detail' with arguments '(2018, 11, 6, 'another post')' not found.
1 pattern(s) tried: ['blog\\/(?P<year>[0-9]+)\\/(?P<month>[0-9]+)\\/(?P<day>[0-9]+)\\/(?P<post>[-a-zA-Z0-9_]+)\\/$']
Here is my templates/blog/base.html file:
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
<link href="{% static "css/blog.css" %}" rel="stylesheet">
</head>
<body>
<div id="content">
{% block content %}
{% endblock %}
</div>
<div id="sidebar">
<h2>My blog</h2>
<p>This is my blog</p>
</div>
</body>
</html>
Here is my templates/blog/post/list.html file:
{% extends "blog/base.html" %}
{% block title %}My Blog{% endblock %}
{% block content %}
<h1>My Blog</h1>
{% for post in posts%}
<h2>
<a href="{{ post.get_absolute_url }}">
{{ post.title }}
</a>
</h2>
<p class="date">
Published {{ post.publish }} by {{ post.author }}
</p>
{{ post.body|truncatewords:30|linebreaks }}
{% endfor %}
{% endblock %}
And the blog/urls file:
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
#post views
path('',views.post_list,name='post_list'),
path('<int:year>/<int:month>/<int:day>/<slug:post>/',
views.post_detail,
name='post_detail'),
]
The blog/views file:
from django.shortcuts import render,get_object_or_404
from .models import Post
def post_list(request):
posts = Post.published.all()
return render(request,'blog/post/list.html',{'posts':posts})
def post_detail(request,year,month,day,post):
post = get_object_or_404(Post,slug=post,
status='published',
published__year=year,
published__month=month,
published__day = day)
return render(request,'blog/post/detail.html',{'post':post})
Please help me solve the problem, i would be very happy because i been stuck in this for a week!
Well, as you pointed that you use Django by example book then your get_absolute_url is:
def get_absolute_url(self):
return reverse('blog:post_detail',
args=[self.publish.year,
self.publish.month,
self.publish.day,
self.slug])
There's an example how to create Post object in book:
You made a mistype and instead of slug='another-post' entered slug='another post'.
What is slug. From Django docs:
slug - Matches any slug string consisting of ASCII letters or numbers,
plus the hyphen and underscore characters. For example,
building-your-1st-django-site.
As you see, spaces are not allowed in slug.
You can delete your post with incorrect slug and create another object.
Or you can fix existing post directly in shell:
from django.utils.text import slugify
post = Post.objects.get(pk=id_of_your_post) # replace with int number
fixed_slug = slugify(post.slug)
post.slug = fixed_slug
post.save()

django create form with materialize modal

As far as I tried, I cannot get the form data or send it to the django view function through the materialize css modal. I'm just a novice in js, ajax and related.
The "CreateView" action for my form is running outside, but it is required to be inside a modal and still get the benefits of using django form validation, security, and so on. I'm using Django version 1.11.
The project has two applications: main that loads the main page, and library that performs actions on book objects. A book has only a title, and so there's a form defined like:
library/forms.py:
from django import forms
from .models import Book
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = [
'title',
]
the project urls definition, mysite/urls.py :
from django.conf.urls import url, include
from django.contrib import admin
from main import views as main_views
urlpatterns = [
url(r'^$', main_views.home, name='home'),
url(r'^books/', include('library.urls')),
url(r'^admin/', admin.site.urls),
]
Home view, main/views.py:
from django.shortcuts import render
def home(request):
return render(request, 'main/home.html')
main/templates/main/home.html:
<html>
<head>
<title>A library</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/css/materialize.min.css">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
{% block body %}
<div class="container">
<!--a class="waves-effect waves-light btn modal-trigger" href="#modal1">Create Book</a-->
<a class="waves-effect waves-light btn modal-trigger" data-target="add_book_modal" href="{% url 'books:create' %}">
Create Book
</a>
<div class="divider"></div>
<div class="section">
<h5>Section 1</h5>
<p>Stuff</p>
</div>
</div>
{% endblock %}
{% include 'library/book_form.html' %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0-beta/js/materialize.min.js"></script>
<script>
$( document ).ready(function() {
$('.modal').modal();
});
</script>
</body>
</html>
The library's urls, library/urls.py:
from django.conf.urls import url
from .views import BookCreateView
app_name='books'
urlpatterns = [
url(r'^create/$', BookCreateView.as_view(), name='create'),
]
library/views.py:
from django.shortcuts import render
from django.views.generic import CreateView
from django.urls import reverse_lazy
from .models import Book
from .forms import BookForm
class BookCreateView(CreateView):
form_class = BookForm
template_name = 'library/book_form.html'
success_url = reverse_lazy('home')
library/templates/library/book_form.html:
<div id="add_book_modal" class="modal">
<div class="modal-content">
{% block body %}
<main>
<h5>Add book information</h5>
{% if form.errors.non_field_errors %}
{{ form.errors.non_field_errors }}
{% endif %}
<form method="POST">
{% csrf_token %}
{{ form.non_field_errors }}
{{ form.source.errors }}
{{ form.source }}
<!--Form content-->
{{form.as_p}}
<!--Form button-->
<button class="btn waves-effect waves-light" type="submit" name="action">Submit
</button>
</form>
</main>
{% endblock %}
</div>
</div>
Any help will be appreciated.
Changing a href link and setting the place of html code where the content will be rendered
main/templates/main/home.html:
...
<a class="waves-effect waves-light btn modal-trigger" href="#modal1">Create Book</a>
...
<!-- Modal Structure -->
<div id="modal1" class="modal">
<div class="modal-content">
<!--Form content goes in here.-->
</div>
</div>
{% endblock %}
<!-- django include tag removed -->
Jquery to render the form in the modal through django's routes
main/templates/main/home.html:
<script>
$( document ).ready(function() {
$('.modal').modal();
$('.modal-content').load("{% url 'books:create' %}");
});
</script>
Finally, book form specifying the way back.
_library/templates/library/book_form.html_:
<h5>Add book information</h5>
{% if form.errors.non_field_errors %}
{{ form.errors.non_field_errors }}
{% endif %}
<form method="POST" action="{% url 'books:create' %}">
{% csrf_token %}
{{ form.non_field_errors }}
{{ form.source.errors }}
{{ form.source }}
<!--Form content-->
{{form.as_p}}
<!--Form button-->
<button class="btn waves-effect waves-light" type="submit" name="action">Submit form
</button>
</form>

Django template extending

I am new with Django and trying to understand how to use templates and I have an issue with template extending. I have 3 templates. the first one in the base.html
{% load staticfiles%}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
<link rel="stylesheet" type="text/css" href="{%static 'css/main.css'%}">
<title>Home</title>
</head>
<body >
<div class="page-header">
<h1>Django Project</h1>
</div>
<div class="content container">
<div class="row">
<div class="col-sm-8">
{%block content %}
{%endblock%}
</div>
<div class="col-sm-4">
{%block lastposts %}
{%endblock%}
</div>
</div>
</div>
</body>
</html>
Second one is post_list.html (which I render from views)
{% extends 'blog/base.html' %}
{% block content %}
{%for post in posts %}
<h1>{{post.title}}</h1>
<p>{{post.text|linebreaks}}</p>
<p><b>Author: </b>{{post.author}}</p>
<p><b>Published Date: </b>{{post.published_date}}</p>
{%endfor%}
{% endblock %}
and latest_posts.html
{% extends 'blog/base.html' %}
{% block lastposts %}
<h3>Latest Posts</h3>
{%for post in posts%}
<h4>{{post.title}}</h4>
{% endfor %}
{% endblock %}
The problem is that the content of latest_posts.html does not show up. I know that something is wrong. In that case how I can use extending in django to to separate my code in these 3 files. Thanks.
*UPDATE
views.py
from django.shortcuts import render
from django.utils import timezone
from .models import Post
# Create your views here.
def post_list(request):
posts = Post.objects.filter(published_date__lte=timezone.now()).order_by('published_date')
return render(request, 'blog/post_list.html', {'posts': posts})
urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.post_list, name='post_list'),
]
If you want to display the contents of latest_posts.html in post_list.html, you'll have to include it
post_list.html
{% extends 'blog/base.html' %}
{% block content %}
{%for post in posts %}
<h1>{{post.title}}</h1>
<p>{{post.text|linebreaks}}</p>
<p><b>Author: </b>{{post.author}}</p>
<p><b>Published Date: </b>{{post.published_date}}</p>
{%endfor%}
{% endblock %}
{%block lastposts %}
{% include 'blog/latest_posts.html' %}
{% endblock %}
latest_posts.html (only remove the extend and block tags)
<h3>Latest Posts</h3>
{%for post in posts%}
<h4>{{post.title}}</h4>
{% endfor %}