coderboy
coderboy

Reputation: 759

How to display a Custom Error Page in Django

I have a list of tables in my application, if a user book an available table it books it correctly without error but if a user books an unavailable table it displays an error page saying "Tables matching query does not exist". I have been trying some ways to get a custom error page or perhaps some nicer interface instead of the page error.

error log

Environment:


Request Method: POST
Request URL: http://localhost:8000/reserve/1/

Django Version: 3.1.4
Python Version: 3.7.3
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'core',
 'dashboard',
 'widget_tweaks',
 'phonenumber_field']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "C:\Users\Habib\Documents\django\FIVERR\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "C:\Users\Habib\Documents\django\FIVERR\venv\lib\site-packages\django\core\handlers\base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Habib\Documents\django\FIVERR\adam_mailk\core\views.py", line 30, in ReserveTable
    table_exists = Tables.objects.get(table_no=request.POST['table'], bar=bar)
  File "C:\Users\Habib\Documents\django\FIVERR\venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\Habib\Documents\django\FIVERR\venv\lib\site-packages\django\db\models\query.py", line 431, in get
    self.model._meta.object_name

Exception Type: DoesNotExist at /reserve/1/
Exception Value: Tables matching query does not exist.

This is a visual image of the error page it displays

views.py

def ReserveTable(request, pk):

    bar = Bar.objects.get(id=pk)
    tables = Tables.objects.filter(bar=bar, status="available")
    form = ReservationForm()
    if request.method == "POST":
        if request.POST['table']:
            request.POST = request.POST.copy()
            table_exists = Tables.objects.get(table_no=request.POST['table'], bar=bar)

            if table_exists.DoesNotExist:
                return redirect(reverse('error-page', kwargs={'message': "This object does not exist"}))

            request.POST['people'] = table_exists.seats
            form = request.POST
            try:
                if table_exists.status == "available":
                    time = form['time']
                    people = form['people']
                    comment = form['comment']
                    date_reserved = form['date_reserved']

                    resrv = Reservation.objects.create(time=time, date_reserved=date_reserved, comment=comment, table=table_exists)
                    resrv.save()
                    table_exists.status = "unavailable"
                    table_exists.save()
                    messages.success(request, "you have successfully booked a new table")
                    return redirect(request.path)
                else:
                    recommend = Tables.objects.filter(seats=table_exists.seats, status="available")
                    messages.error(request, "Unable to book a new table. Table Not available.")
                    request.session['recommend'] = list(recommend)
                    return redirect(request.path)

            except Exception as e:
                messages.error(request, "Unknown error")
                return redirect(request.path)

    context = {"bar":bar, "form":form, "tables": tables}
    return render(request, "website/reservation.html", context)

def error_page(request, message):
    return render(request, 'website/error_page.html', {'message': message})

models.py

class Bar(models.Model):

    status = (
            ("open", "open"),
            ("closed", "closed"),
            ("pending", "pending"),
        )

    user_id = models.OneToOneField(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=50)
    address = models.CharField(max_length=100)
    opening_time = models.TimeField()
    closing_time = models.TimeField()
    status = models.CharField(choices=status, default="pending", max_length=14)
    image = models.ImageField(upload_to='images/bars', default='images/bars/default.jpg')

    def __str__(self):
        return self.name

class Tables(models.Model):

    status = (
            ("available", "available"),
            ("unavailable", "unavailable"),
        )

    table_no = models.CharField(max_length=14, unique=False)
    status = models.CharField(choices=status, default="unavailable", max_length=14)
    seats = models.IntegerField()
    bar = models.ForeignKey(to=Bar, on_delete=models.CASCADE)

    def __str__(self):
        return self.table_no


class Reservation(models.Model):

    status_choices = (
        ("pending", "pending"), 
        ("confirmed", "confirmed")
    )

    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)
    email = models.EmailField()
    phone = PhoneNumberField(blank=True)
    people = models.IntegerField(default=1)
    time = models.TimeField()
    date_reserved = models.DateField()
    date_booked = models.DateTimeField(auto_now_add=True)
    status = models.CharField(max_length=10, choices=status_choices, default="confirmed")
    comment = models.TextField(blank=True)
    table = models.ForeignKey(Tables, on_delete=models.CASCADE)

    def __str__(self):
        return self.first_name

Upvotes: 0

Views: 1207

Answers (1)

SLDem
SLDem

Reputation: 2182

• Create a view that accepts a message:

def error_page(request, message):
    return render(request, 'error_page.html', {'message': message})

• Create your template:

{% extends 'base.html' %}
{% block content %}

{{ message }}

{% endblock %}

• When an error occurs in your code simply redirect to this view with the message like:

if object.DoesNotExist:
    return redirect(reverse('error_page', 
                            kwargs={'message': "This object does not exist ( or something )"})

UPDATE

You could also wrap your function in try -> except block like this:

def ReserveTable(request, pk):
    try:
        bar = Bar.objects.get(id=pk)
        tables = Tables.objects.filter(bar=bar, status="available")
        form = ReservationForm()
        if request.method == "POST":
            if request.POST['table']:
                request.POST = request.POST.copy()
                table_exists = Tables.objects.get(table_no=request.POST['table'], bar=bar)

                 if table_exists.DoesNotExist:
                    return redirect(reverse('error-page', kwargs={'message': "This object does not exist"}))

                request.POST['people'] = table_exists.seats
                form = request.POST
                try:
                    if table_exists.status == "available":
                        time = form['time']
                        people = form['people']
                        comment = form['comment']
                        date_reserved = form['date_reserved']

                        resrv = Reservation.objects.create(time=time, date_reserved=date_reserved, comment=comment, table=table_exists)
                        resrv.save()
                        table_exists.status = "unavailable"
                        table_exists.save()
                        messages.success(request, "you have successfully booked a new table")
                        return redirect(request.path)
                    else:
                        recommend = Tables.objects.filter(seats=table_exists.seats, status="available")
                        messages.error(request, "Unable to book a new table. Table Not available.")
                        request.session['recommend'] = list(recommend)
                        return redirect(request.path)

    except Exception as ex:
        return redirect(reverse('error_page', kwargs={'message': ex})

Upvotes: 1

Related Questions