I'm having problem with Django templates not receiving any data in image.url when having more than one object in context QuerySet all other data is working fine. If there is only one object in QuerySet, image.url works fine. I'm storing images on S3 and there is nothing wrong with the images or the bucket permission.
I'm new with Django templates is there anything I'm missing?
Here is the code:
models.py
`
from django.db import models
from django.core.validators import MaxValueValidator, MinValueValidator
from django.utils.translation import gettext_lazy as _
from site_content.models import PageCategory, Page
from site_content.utils import file_upload_to
class PpcOffersPagesManager(models.Manager):
def get_queryset(self):
return super(PpcOffersPagesManager, self) \
.get_queryset() \
.filter(page_category__category_name="ppc-offer-page")
class PpcOfferPages(Page):
objects = PpcOffersPagesManager()
class Meta:
proxy = True
def __str__(self):
return self.page_name
def save(self, *args, **kwargs):
self.page_category = PageCategory.objects.get(category_name="ppc-offer-page")
self.page_site_type = "ppc"
super(PpcOfferPages, self).save(*args, **kwargs)
class PpcOfferContent(models.Model):
related_page = models.ForeignKey(
Page, verbose_name=_("Page"),
related_name="ppc_offer_content",
on_delete=models.SET_NULL,
null=True
)
order = models.IntegerField(verbose_name=_("Order of offer appearance"), default=0)
image = models.ImageField(
verbose_name=_("Casino banner image"),
upload_to=file_upload_to,
null=True,
blank=True,
help_text="Casino banner image, Size (300x500)"
)
header = models.CharField(
verbose_name=_("Header text"),
max_length=500,
null=False,
blank=False
)
is_active = models.BooleanField(verbose_name=_("Is offer active"), default=True)
class Meta:
verbose_name = _('PPC_Offer Page Content')
verbose_name_plural = _('PPC_Offer Page Content')
def __str__(self):
return self.related_page.page_name
`
views.py
`
from django.views.generic import DetailView
from ppc_site_control.models import PpcOfferContent
class PpcOffersDetailView(DetailView):
model = PpcOfferContent
def get_template_names(self):
page = self.model.objects \
.filter(related_page__slug = self.kwargs['slug']) \
.first().related_page.page_template.template_path
return page
def get_object(self):
return self.model.objects \
.filter(related_page__slug=self.kwargs['slug']) \
.filter(is_active=True) \
.order_by('offer_order')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
`
.html
`
{% extends "slotsselection/base.html" %}
{% load i18n static reviews sstags %}
{% for offer in object %}
<div>
<div >
<img loading="lazy" src="{{offer.offer_image.url}}" alt="image">
</div>
<div>
<p>{{offer.header}}</p>
<p>{{offer.is_active }}</p>
</div>
<div>
{% endfor %}
`
I tried sending data in the context as new key and adding QuerySet object again with .values()(to exclude possibility of problem with "get_object" query) still have the same result. When I remove the images from template, all other data is displayed accordingly, without images.
I also tried with ListView same error
ValueError The 'image' attribute has no file associated with it.
Data in context:
`{'object': <QuerySet [<PpcOfferContent: PPC PageName>,
<PpcOfferContent: PPC PageName>, <PpcOfferContent: PPC PageName>,
<PpcOfferContent: PPC PageName>]>, 'view':
<ppc_site_control.views.PpcOffersDetailView object at 0x7f2d8230f430>}
`
The problem was caused from missing images because they were not required in the model the simplest solution is adding "if" condition in the template:
I also manage to find workaround:
views.py
then in the context data I added
.html
and in html I removed .url to get the half of the link as string and added media_url
not best approach but it works to.