I need to extend the (generic.DetailView):
to include my second class, PostImage
.
According to the documentation (https://docs.djangoproject.com/en/4.0/topics/class-based-views/generic-display/),
class PostDetail(generic.DetailView):
model = Post
template_name = 'post_detail.html'
should include something like this:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['image_list'] = PostImage.objects.all()
return context
models.py
from django.db import models
from django.contrib.auth.models import User
from django.forms import ImageField
from django.utils.safestring import mark_safe
STATUS = ( #tuple
(0,"Draft"),
(1,"Publish")
)
# Create your models here.
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
updated_on = models.DateTimeField(auto_now= True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
image = models.ImageField(upload_to='images', null=True, blank=True)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
class PostImage(models.Model):
post = models.ForeignKey(Post, default=None, on_delete=models.CASCADE)
image = models.ImageField(upload_to='images', null=True, blank=True)
def __str__(self):
return self.post.title
views.py
from django.views import generic
from .models import Post, PostImage
# Create your views here.
class PostList(generic.ListView):
queryset = Post.objects.filter(status=1).order_by('-created_on')
template_name = 'index.html'
class PostDetail(generic.DetailView):
model = Post
template_name = 'post_detail.html'
urls.py
from . import views
from django.urls import path
urlpatterns = [
path('', views.PostList.as_view(), name='home'),
path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'),
]
Can I leave the urls unchanged?
post_detail.html
{% extends 'base.html' %} {% block content %}
{% load static %}
<div >
<div >
<div >
<div >
<h1>{% block title %} {{ object.title }} {% endblock title %}</h1>
<p >{{ post.author }} | {{ post.created_on }}</p>
<!-- <img src= "{% url 'home' %}{{ post.image }}" alt="Card image cap"> -->
<img src="{% get_media_prefix %}{{ post.image }}" alt="Recipe Image Main">
<p ><pre >{{ object.content }}</pre></p>
{# {% lorem 3 p %} #}
</div>
</div>
{% block sidebar %} {% include 'sidebar.html' %} {% endblock sidebar %}
</div>
</div>
{% endblock content %}
Right now post.image
returns the image in the template, however, I need postimage.image
(basically my second class in the models) to return as well.. (doesn't work). What am I missing?.. Reading a buncha docs.
CodePudding user response:
You pass image_list
but don't call it. You should use a for loop in your template.
{% for img in image_list %}
{{ img.post }}
{{ img.image }}
{% endfor %}
CodePudding user response:
Accessing method calls¶
Most method calls attached to objects are also available from within templates. This means that templates have access to much more than just class attributes (like field names) and variables passed in from views. For example, the Django ORM provides the “entry_set” syntax for finding a collection of objects related on a foreign key.
Since your two models have a ForeignKey used to relate to each other. I think you can just utilize reverse lookup _set
without adding the child model in the context. You can just call it in your templates something like this:
{% for post_image in post.postimage_set.all %}
{{ post_image.image }}
{% endfor %}
Reference: Django Template: Accessing Method calls