In this previous question I asked about using data from one Django application in another. I wanted to use blog data from my blog application in my pages application. The goal being that my site homepage would show the 3 most recent entries.
The answer provided was acceptable at the time. However, I've since wanted to now set the blog items that appear on my homepage to act as links to the blog item itself but the blog items on my homepage have a different url path. Is there any way around this?
Here is my code:
Blog
from .views import (
BlogListView,
BlogUpdateView,
BlogDetailView,
BlogDeleteView,
BlogCreateView,
)
urlpatterns = [
path('<int:pk>/edit/',
BlogUpdateView.as_view(), name='Blog_edit'),
path('<int:pk>/',
BlogDetailView.as_view(), name='Blog_detail'),
path('<int:pk>/delete/',
BlogDeleteView.as_view(), name='Blog_delete'),
path('new/', BlogCreateView.as_view(), name='Blog_new'),
path('', BlogListView.as_view(), name='Blog_list'),
]
models.py
class Blog(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(
get_user_model(),
on_delete=models.CASCADE,
)
thumb = models.ImageField(blank=True, null=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('Blog_detail', args=[str(self.id)])
views.py
class BlogListView(ListView):
model = Blog
template_name = 'blog_list.html'
class BlogDetailView(DetailView):
model = Blog
template_name = 'blog_detail.html'
login_url = 'login'
class BlogUpdateView(LoginRequiredMixin, UpdateView):
model = Blog
fields = ('title', 'body', 'thumb')
template_name = 'blog_edit.html'
login_url = 'login'
def test_func(self):
obj = self.get_object()
return obj.author == self.request.user
class BlogDeleteView(LoginRequiredMixin, DeleteView):
model = Blog
template_name = 'blog_delete.html'
success_url = reverse_lazy('blog_list')
login_url = 'login'
def test_func(self):
obj = self.get_object()
return obj.author == self.request.user
class BlogCreateView(LoginRequiredMixin, CreateView):
model = Blog
template_name = 'blog_new.html'
fields = ('title', 'body', 'thumb')
login_url = 'login'
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
pages
urls.py
urlpatterns = [
path('', HomePageView, name='home'),
]
views.py
def HomePageView(request):
context = {}
blog = Blog.objects.order_by('-date')[:3]
context['blog']=blog
return render(request,'home.html',context)
home.html
{% extends 'base.html' %}
{% block title %}Home{% endblock title %}
{% block content %}
<div class="jumbotron">
<h1 class="display-4">Lakeland Cycle Club</h1>
<p class="lead">The home of cycling in Fermanagh.</p>
<p class="lead">
<a class="btn btn-primary btn-lg" href="{% url 'blog_list' %}" role="button">View All Club News</a>
</p>
{% for new in blog%}
<div class="card" style="width: 300px; display: inline-block; margin: 5px; vertical-align: top;">
<div class="card-header">
<span class="font-weight-bold">
{{ new.title }}
</span> ·
<span class="text-muted">by {{ new.author }} | {{ new.date }}</span>
</div>
<div class="card-body">
{% if blog.thumb %}
<p align="center"><img src="{{ new.thumb.url }}" /></p>
{% endif %}
<p>{{ new.body | linebreaks | truncatewords:30 }}
</div>
</div>
{% endfor %}
{% endblock content %}
More info.
I think if I add a URL to my title({{ new.title }}
) it might work as I want. I tried <a href="{% url 'blog_detail' %}">{{ new.title }}</a>
but got this error:
django.urls.exceptions.NoReverseMatch: Reverse for 'blog_detail' with no arguments not found. 1 pattern(s) tried: ['blog/(?P<pk>[0-9]+)/$']
The reason is most likely because each item in my home page has no way of identifying the primary key for the specific blog entry. If I change the url to blog_list
no primary key is required so I'm taken to the blog_lost page without any issue. How can I add a URL link and ensure it links to the correct blog_detail
post?
I made the following changes:
templates/home.html
I changed
<span class="font-weight-bold">
{{ new.title }}
</span> ·
for
<span class="font-weight-bold">
<a href="{% url 'pages_blog_detail' new.pk %}">{{ new.title }}</a>
</span> ·
pages/urls.py
I added
from blog.views import BlogDetailView
and changed
urlpatterns = [
path('', HomePageView, name='home'),
]
to
urlpatterns = [
path('blog/<int:pk>/',
BlogDetailView.as_view(), name='pages_blog_detail'),
path('', HomePageView, name='home'),
]