user2770624
user2770624

Reputation: 393

QuerySet Returns Empty List Instead of error

I think my queryset is returning an empty list instead of a "Does not exist error". I want it to return an error so that I can return an alternative message. The HTML is returning an empty bullet point instead of the desired message.

view.py

def results(request, foo_id):

    template_name = 'results.html'
    foo = Foo.objects.get(id=foo_id)
    foo_id = foo_id
    try:    
        foobars = FooBar.objects.filter(foo__foo=foo.foo)

        return render(request, template_name, {'foobars': foobars, 
            'zipcode':zipcode, 'foo_id':foo_id})

    except FooBar.DoesNotExist:
        message = 'Sorry there are no FooBar with that foo'
        return render(request, template_name, {'message':message, 
            'foo_id':foo_id})

models.py

class Foo(models.Model):
   foo = models.IntegerField(null=True)

class FooBar(models.Model):
    foo = models.ForeignKey('Foo')
    title = models.CharField(max_length=100)
    description = models.CharField(max_length=400, null=False, blank=True )


    def __str__(self): 
        return self.title

results.html

<html>

<h2>Title</h2>

<ul id='id_results'>
    {% for foobar in foobars%}
        <li>{{ foobar.name }}</li>
    {% empty %}
        <li> {{ message }} </li>
    {% endfor %}
</ul>

<a href= "/new_foobar/">New FooBar </a>

Upvotes: 1

Views: 2128

Answers (1)

Rahul Gupta
Rahul Gupta

Reputation: 47846

.filter() does not raise an exception if objects does not exist in the queryset, it returns an empty list [] instead.

We could have used a .get() on the queryset which raises this exception in case no objects exist. But, we won't be able to use it as there might be multiple objects in the queryset matching the criteria and in case of multiple objects being returned, it raises an exception.

get() raises MultipleObjectsReturned if more than one object was found.

You can instead check using the booleanness of foobars and in case of it being an empty list, display the message.

def results(request, foo_id):

    template_name = 'results.html'
    foo = Foo.objects.get(id=foo_id)
    foo_id = foo_id

    foobars = FooBar.objects.filter(foo__foo=foo.foo)
    if foobars: # check if there are any matching objects    
        return render(request, template_name, {'foobars': foobars, 
            'zipcode':zipcode, 'foo_id':foo_id})   
    else: # no matching objects
        message = 'Sorry there are no FooBar with that foo' # display the message
        return render(request, template_name, {'message':message, 
            'foo_id':foo_id})

Upvotes: 1

Related Questions