Объект 'Uploads' не является итерируемым в Django
Я пытаюсь сделать так, чтобы каждый объект модели имел свою собственную страницу со всеми другими объектами модели, прикрепленными к ней, используя id модала, я пытался использовать {{ img.queryset.all.id }} html тег для отображения фотографии, но это не сработало. Я знаю, что проблема либо в views.py, либо в single_page.html, и, возможно, в models.py, но я считаю, что это вряд ли проблема. Когда я нажимаю на фотографию, она переводит на страницу с иконкой фотографии, но не отображает ее, потому что фотография неизвестна. Каждый раз, когда я использую {% for x in img %}, он говорит, что объект 'Uploads' не является интегрируемым. Если кто-то может помочь, было бы здорово.
modals.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE, null = False, blank = True)
first_name = models.CharField(max_length = 50, null = True, blank = True)
last_name = models.CharField(max_length = 50, null = True, blank = True)
phone = models.CharField(max_length = 50, null = True, blank = True)
email = models.EmailField(max_length = 50, null = True, blank = True)
bio = models.TextField(max_length = 300, null = True, blank = True)
profile_picture = models.ImageField(default = 'default.png', upload_to = "img/%y", null = True, blank = True)
def __str__(self):
return f'{self.user.username} Profile'
class Uploads(models.Model):
title = models.CharField(max_length = 500, null = True,)
artiste = models.CharField(max_length=500, null = True,)
album = models.ForeignKey('Album', on_delete=models.SET_NULL,null=True,blank=True)
time_length=models.DecimalField(max_digits=20, decimal_places=2,blank=True, null = True,)
audio_file=models.FileField(upload_to='musics/',validators=[validate_is_audio], null = True,)
caption = models.CharField(max_length = 100, blank=True)
file = models.ImageField(upload_to = "img/%y", null = True)
profile = models.ForeignKey(Profile, on_delete = models.CASCADE, default = None, null = True)
id = models.AutoField(primary_key = True, null = False)
def __str__(self):
return str(self.file) and f"{self.id}"
class Album(models.Model):
name=models.CharField(max_length=400)
views.py
def profile(request, user):
img = Uploads.objects.filter(profile_id = request.user.profile) #Make sure only your account *images stays on the page
profile = Profile.objects.filter(user = request.user)
context = {"profile": profile, "img": img}
return render(request, "main/profile.html", context)
def single_page(request, id):
img = Uploads.objects.filter(id = id).first()
profile = Uploads.objects.filter(id = request.user.id)
context = { "img": img, "profile": profile}
return render(request, "main/single_page.html", context)
single_page.html
{% block content %}
<body>
{% for x in img %}
<p>{{title}}</p>
<img src="{{x.file.url}}" height="100%" width="100%" class="myImg">
{% endfor %}
</body>
{% endblock %}
Поскольку вы фильтруете профиль по id, а также указываете first, невозможно выполнить цикл, поскольку first будет отображать первый объект, поэтому цикл будет работать только в том случае, если вы добавите что-то вроде этого:
# Your view.py
def single_page(request, id):
img = Uploads.objects.filter(id=id)
profile = Uploads.objects.filter(id = request.user.id)
context = { "img": img, "profile": profile}
return render(request, "main/single_page.html", context)
Ваш Html
{% block content %}
<body>
{% for x in img.all %}
<p>{{title}}</p>
<img src="{{x.file.url}}" height="100%" width="100%" class="myImg">
{% endfor %}
</body>
{% endblock %}
Если img является объектом, вы не можете выполнять итерации над ним, поэтому цикл for не является правильной идеей. Вы должны иметь возможность получить доступ к его url с помощью: {{ img.file.url }}.
Не используйте id в качестве переменной, это встроенная функция. Не фильтруйте Uploads.id по request.user.id, потому что это не будет работать. Это другая модель.
Для одиночной фотографии вы должны сделать в views:
from django.shortcuts import get_object_or_404
def single_page(request, img_id):
img = get_object_or_404(Uploads, id=img_id)
context = {"img": img}
return render(request, "main/single_page.html", context)
single_page.html:
{% block content %}
<body>
<p>{{ img.title }}</p>
<img src="{{ img.file.url }}" height="100%" width="100%" class="myImg">
</body>
{% endblock %}
Если у вас есть больше фотографий одного User, вы можете найти их с помощью:
images = Uploads.objects.filter(profile=self.request.user.profile)
context = {"images": images}
А в шаблоне:
{% for img in images %}
<p>{{ img.title }}</p>
<img src="{{ img.file.url }}" height="100%" width="100%" class="myImg">
{% endfor %}
Если вы хотите получить profile, не ищите его с помощью filter, потому что вы получите QuerySet, а не экземпляр объекта. Чтобы получить одиночный объект, вы должны сделать так, как я показывал вам раньше:
profile = get_object_or_404(Profile, user=request.user)
# or
profile = Profile.objects.get(user=request.user)
или если вы действительно, действительно предпочитаете filter метод:
profile = Profile.objects.filter(user=request.user).first()
Я думал, что опубликовал свой ответ раньше, но забыл нажать кнопку post, поэтому извините за поздний ответ. Моя проблема была решена, когда я удалил цикл for,
<img src="{{img.file.url}}" height="30%" width="30%" class="myImg">
<audi src="{{img.audio_file.url}}" height="30%" width="30%" class="myImg">
<p>{{img.title}}</p>
<p>{{img.artiste}}</p>
Мне казалось, что я уже пробовал это раньше и это не работало (удаление цикла for), но, возможно, я что-то выдумываю. Я также жестко закодировал, где я поместил 1 в качестве id как такового
img = Uploads.objects.filter(id = 1).first()
Возможно, это что-то вызвало, но независимо от этого я устранил проблему, и вот мой окончательный views.py
def single_page(request, id):
img = Uploads.objects.filter(id = id).first()
profile = Uploads.objects.filter(id = request.user.id)
context = { "img": img, "profile": profile}
return render(request, "main/single_page.html", context)