Home > database >  'Uploads' object is not iterable in Django
'Uploads' object is not iterable in Django

Time:02-06

I am trying to have each model object have it's own page with all the other model objects attached to it, using the modal id, I tried using the {{ img.queryset.all.id }} html tag to display the photo, but that didn't work. I know the problem is in either the views.py or single_page.html, and maybe the models.py but I believe that is unlikely the problem. When I click onto the photo it bring it to a page with the photo icon, it doesn't display it because the photo is unknown. While every time I use {% for x in img %} it says 'Uploads' object is not integrable. If anyone could help that would be great.

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%"  >
    {% endfor %}


</body>
{% endblock %}

CodePudding user response:

Since you are filtering through the profile by id and also specifying first it wouldn't be possible to loop through as first would render the first object and so the loop will only work with you adding (img.all) by doing something like this:

# 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)

Your Html


{% block content %}
<body>
    {% for x in img.all %}
    <p>{{title}}</p>

    <img src="{{x.file.url}}" height="100%" width="100%"  >
    {% endfor %}

</body>
{% endblock %}

CodePudding user response:

I thought I posted my answer earlier, but I forgot to hit post so sorry for the late response. My problem was solved when I removed the for loop,



    <img src="{{img.file.url}}" height="30%" width="30%"  >
    <audi src="{{img.audio_file.url}}" height="30%" width="30%"  >
    <p>{{img.title}}</p>
    <p>{{img.artiste}}</p>


I thought I tried this before and it wasn't working (removing the for loop), but maybe I was imagining things. I also hard coded to where I put 1 as the id as such

img = Uploads.objects.filter(id = 1).first()

maybe that triggered something, but regardless I fixed the problem and this is my final 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)

CodePudding user response:

If img is an object, you cannot iterate over it, so for loop is not valid idea. You should be able to access it's url with: {{ img.file.url }}.

Don't use id as variable, it's builtin function. Don't filter Uploads.id by request.user.id because it's not going to work. It's different model.

For single photo you should do in 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%"  >

</body>
{% endblock %}

If you have more pictures of one User, you can find them with:

images = Uploads.objects.filter(profile=self.request.user.profile)
context = {"images": images}

And in template:

{% for img in images %}

    <p>{{ img.title }}</p>

    <img src="{{ img.file.url }}" height="100%" width="100%" >

{% endfor %}

And if you want to get profile, don't search it with filter, because you will get QuerySet, not an object instance. To get single object you should do as I've showed you before:

profile = get_object_or_404(Profile, user=request.user)
# or
profile = Profile.objects.get(user=request.user)

or if you really, really prefer filter method:

profile = Profile.objects.filter(user=request.user).first()
  •  Tags:  
  • Related