Hi I am letting the user upload multiple images per project but so far the images are not displayed. In projects.html
all projects should be displayed and the title and the describtion work so far. But the main-image doesn´t show up. In single-project
all images should be displayed.
What do I have to change in my models.py?
Thanks in forward
models.py
class Project(models.Model):
title = models.CharField(max_length=200)
describtion = models.TextField(null=True, blank=True)
id = models.UUIDField(default=uuid.uuid4, unique=True, primary_key=True, editable=False)
class ProjectImage(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
featured_images = models.FileField()
forms.py
class ProjectForm(ModelForm):
featured_images = forms.ImageField(widget=ClearableFileInput(attrs={'multiple':True}))
class Meta:
model = Project
fields = ['title', 'describtion', 'featured_images']
views.py
def createProject(request):
form = ProjectForm()
if request.method == 'POST':
form = ProjectForm(request.POST)
images = request.FILES.getlist('image')
if form.is_valid():
project = form.save()
for i in images:
ProjectImage(project=project, image=i).save()
context = {'form':form}
return render(request, 'projects/project_form.html', context)
def projects(request):
projects = Project.objects.all()
context = {"projects":projects}
return render(request, 'projects/projects.html', context)
def project(request, pk):
projectObj = Project.objects.get(id=pk)
return render(request, 'projects/single-project.html', {'project':projectObj})
projects.html
{% for project in projects %}
<div >
<div >
<a href="{% url 'project' project.id %}" >
<img src="{{project.featured_images.url}}" alt="project thumbnail" />
<div >
<h3 >{{project.title}}</h3>
<h3 >{{project.price}} €</h3>
</div>
</a>
</div>
</div>
{% endfor %}
single-project.html
<h3 >{{project.title}}</h3>
<h3 >{{project.price}} €</h3>
<h3 >Infos zum Produkt</h3>
{{project.describtion}}
project_form.html
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div >
<label for="formInput#text">{{field.label}}</label>
{{field}}
</div>
{% endfor %}
<input type="submit" value="Submit" />
</form>
CodePudding user response:
To access the images of a project, you need to use the related manager in your templates:
projects.html
{% for project in projects %}
<div >
<div >
<a href="{% url 'project' project.id %}" >
<img src="{{project.projectimage_set.all.0.featured_images.url}}" alt="project thumbnail" />
<div >
<h3 >{{project.title}}</h3>
<h3 >{{project.price}} €</h3>
</div>
</a>
</div>
</div>
{% endfor %}
I assumed that by "main-image" you mean the first image of the project.
single-project.html
<h3 >{{project.title}}</h3>
<h3 >{{project.price}} €</h3>
<h3 >Infos zum Produkt</h3>
{{project.describtion}}
{% for projectimage in project.projectimage_set.all %}
<img src="{{projectimage.featured_images.url}}"/>
{% endfor %}
To avoid the N 1 query problem, you can also change the query in your view:
views.py
def projects(request):
projects = Project.objects.all().prefetch_related('projectimage_set')
context = {"projects":projects}
return render(request, 'projects/projects.html', context)