Problem: I cannot get images to appear on my template plant_detail.html. I think I'm calling on variables incorrectly, but not sure what to change.
Context:
I created a model PlantImage, that allows me to associate multiple images within my model Plant.
I then created a class-based view PlantDetailView to link the two models, PlantImage and Plant together.
However, now when I try to display those images in the template plant_detail.html, nothing will appear. How can I get images to appear on my template?
I tried reading through the Django documentation, reading articles, and watching youtube videos, but I'm not sure what I'm missing or need to edit.
My files:
plants/models.py
class Plant(models.Model):
name = models.CharField(max_length=120)
slug = models.SlugField(null=False, unique=True)
description = models.TextField()
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("plant_detail", kwargs={"slug": self.slug})
class PlantImage(models.Model):
plant = models.ForeignKey(Plant, default=None, on_delete=models.CASCADE)
images = models.ImageField(upload_to = 'images/')
def __str__(self):
return self.plant.name
plants/views.py
def plant_index(request):
plant_objects = Plant.objects.all()
context = {'plant_objects': plant_objects}
return render(request, 'plants/plant_index.html', context)
class PlantDetailView(DetailView):
model = Plant
template_name = 'plants/plant_detail.html'
slug = 'slug'
def get_context_data(self, **kwargs):
context = super(PlantDetailView, self).get_context_data(**kwargs)
context['plant_images'] = PlantImage.objects.all()
return context
plant_detail = PlantDetailView.as_view()
plants/urls.py
from django.urls import path
from .views import plant_index, plant_detail
app_name = 'plants'
urlpatterns = [
# ex: /plants/
path('', plant_index, name='plant_index'),
# ex: /plants/pothos/
path("<slug:slug>", plant_detail, name="plant_detail"),
]
plants/plant_detail.html
{% block content %}
<body>
<h1> {{ plant.name }} </h1>
<br>
<p> <b>Latin Name: </b>{{ plant.latin_name }} </p>
<br>
<p><b>Description: </b></p>Dj
<p> {{ plant.description }} </p>
<br>
<br>
<p>Images:</p>
<br>
{% for image in plant_images %}
<p><img src="{{ plant.images }}" width="300px"></p>
{% endfor %}
</body>
{% endblock content %}
settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = str(BASE_DIR.joinpath('mediafiles'))
Screenshot of the model in admin:
CodePudding user response:
The code "PlantImage.objects.all()" gets not only specific image related plant but another images.
so if you want to access PlantImage from Plant, you have to write related_name.
https://docs.djangoproject.com/en/4.0/ref/models/fields/#django.db.models.ForeignKey.related_name
class PlantImage(models.Model):
plant = models.ForeignKey(Plant, default=None, on_delete=models.CASCADE, related_name="plant_images")
...
ImageField inherit FileField. so, you have to know something of Filefield functions.
https://docs.djangoproject.com/en/4.0/ref/models/fields/#filefield-and-fieldfile
if you want to show images, add '.url' like this.
{% for image in plant.plant_images.all %}
<p><img src="{{ image.images.url }}" width="300px"></p>
{% endfor %}