Josh
Josh

Reputation: 285

Django - Ignore index error?

So I have a site where users can upload pictures attached to events which will then be shown in an instagram-type layout on the event page. Because of the way my page is designed, though, I can't just iterate the list. I have to call on each object individually (because I am putting them in various spots all over the page, not just in a simple list). Indexing has worked okay for this, but if I try to open an event which has less than the index amount, I get an error. Is there any way to avoid this? Or does anyone have an alternative solution? I need to be able to call on each item in a list individually so that I can individually format where it is and where it links to.

views.py:

def event_detail(request, slug):
    Event = Event.objects.get(slug=slug)
    image1 = Image.objects.filter(event__slug=slug)[0]
    image2 = Image.objects.filter(event__slug=slug)[1]
    image3 = Image.objects.filter(event__slug=slug)[2]
    return render(request, 'events/event_detail.html', {
        'event': event,
        'image1': image1,
        'image2': image2,
        'image3': image3,

})

Then I call on the objects with {{ image1.url }} etc.

Right now it's set up to support 3 (or more) images, but if the event has less than 3 images attached, I get the error.

Very much open to alternative ways to model this as well, if anyone has ideas.

Upvotes: 0

Views: 196

Answers (2)

Bijoy
Bijoy

Reputation: 1131

You can send the Images and events to html page as @karthikr mentioned

def event_detail(request, slug):
Event = Event.objects.get(slug=slug)
images = Image.objects.filter(event__slug=slug)[:3]
return render(request, 'events/event_detail.html', {
    'event': event,
    'images': images})

and then in html pages you can call the images by indexing If you want to call it individually by doing.

{{ images.0.url }} {{ images.1.url }}

Its using indexing in Templates. If you are sure there would be specified number of images on the template

Upvotes: 1

karthikr
karthikr

Reputation: 99640

The issue occurs because you are evaluating the queryset by indexing. So it would naturally fail if the queryset does not have 3 images.

One thing you could do is, handle it slightly differently:

def event_detail(request, slug):
    Event = Event.objects.get(slug=slug)
    images = Image.objects.filter(event__slug=slug)[:3]
    return render(request, 'events/event_detail.html', {
        'event': event,
        'images': images
})

Now you could do :

{% for image in images %}
    {% image.url %}
{% endfor %}

This way, [:3] would slice the queryset "safely", and the template would only render the objects that are present in the images queryset

Edit:

To accommodate the sets of 2 your are looking for, another thing you could do is:

def event_detail(request, slug):
    Event = Event.objects.get(slug=slug)
    image_set_1 = Image.objects.filter(event__slug=slug)[:2]
    image_set_2 = Image.objects.filter(event__slug=slug)[2:4]
    image_set_3 = Image.objects.filter(event__slug=slug)[4:6]
    return render(request, 'events/event_detail.html', {
        'event': event,
        'image_set_1': image_set_1,
        'image_set_2': image_set_2,
        'image_set_3': image_set_3,
})

Now this slice is "safe", so you can render it wherever you want.

Upvotes: 3

Related Questions