pythondjango

How to solve Key Error in views.py in Django


When I'm trying to fill out the form on the website, it throws me a Key Error. The status of POST http request is 500 and data don't save in db. Here is views.py file:

@csrf_exempt
def bookings(request):
    if request.method == 'POST':
        data = json.load(request)
        exist = Reservation.objects.filter(reservation_date=data['reservation_date']).filter(
            reservation_slot=data['reservation_slot']).exists()
        if exist==False:
            booking = Reservation(
                name=data['first_name'],
                phone_number=data['phone_number'],
                email=data['email'],
                reservation_date=data['reservation_date'],
                reservation_slot=data['reservation_slot'],
            )
            booking.save()
        else:
            return HttpResponse("{'error':1}", content_type='application/json')
    
    date = request.GET.get('date',datetime.today().date())

    bookings = Reservation.objects.all().filter(reservation_date=date)
    booking_json = serializers.serialize('json', bookings)

    return HttpResponse(booking_json, content_type='application/json')

This is models.py:

class Reservation(models.Model): 
    name = models.CharField(max_length=100)
    phone_number = models.IntegerField()
    email = models.EmailField()
    reservation_date = models.DateField()
    reservation_slot = models.SmallIntegerField(default=10)

    
    def __str__(self):
        return self.name + " " + self.surname

This is forms.py:

class ReservationForm(ModelForm): 
    class Meta: 
        model = Reservation
        fields = "__all__"

Error message:

File "/home/prabhu/Documents/Projects/alcudia-web/my_alcudia/baseweb/views.py", line 50, in bookings
    email=data['email'],
KeyError: 'email'

And this is HTML form:

   <p>
   <label for="email">Email: </label>
   <input type="email" placeholder="Your email" maxlength="200" required="" id="email">
   </p>

Will be glad for any suggestions.


Solution

  • You forgot one element: the name="…" [mdn-doc] of the email input element:

    <input type="email" name="email" placeholder="Your email" maxlength="200" required="" id="email">

    that being said, validation of input is tricky, therefore it is better to let a Django form validate the data. You don't have to render that form in the template if you don't want to.


    Note: Please don't use @csrf_exempt [Django-doc] as standard practice: it makes your site vulnerable to Cross-site request forgery (CSRF) [wiki] where one can for example make links that perform POST actions. By working with a CSRF cookie, the SameSite policy of cookies will prevent this from happening.