Django serializer.save() gives back a HTTP 500 error response
Question:
I have the following straightforward setup: a folder order
with a models.py
file,
from django.contrib.auth.models import User
from django.db import models
from product.models import Product
class Order(models.Model):
user = models.ForeignKey(User, related_name='orders', on_delete=models.CASCADE)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
email = models.CharField(max_length=100)
address = models.CharField(max_length=100)
zipcode = models.CharField(max_length=100)
place = models.CharField(max_length=100)
phone = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
paid_amount = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
stripe_token = models.CharField(max_length=100)
class Meta:
ordering = ['-created_at',]
def __str__(self):
return self.first_name
class OrderItem(models.Model):
order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
product = models.ForeignKey(Product, related_name='items', on_delete=models.CASCADE)
price = models.DecimalField(max_digits=8, decimal_places=2)
quantity = models.IntegerField(default=1)
def __str__(self):
return '%s' % self.id
a serializers.py
file
from rest_framework import serializers
from .models import Order, OrderItem
class OrderItemSerializer(serializers.ModelSerializer):
class Meta:
model = OrderItem
fields = [
"price",
"product",
"quantity",
]
class OrderSerializer(serializers.ModelSerializer):
items = OrderItemSerializer(many=True)
class Meta:
model = Order
fields = [
"id",
"first_name",
"last_name",
"email",
"address",
"zipcode",
"place",
"phone",
"stripe_token",
"items",
]
def create(self, validated_data):
items_data = validated_data.pop('items')
order = Order.objects.create(**validated_data)
for item_data in items_data:
OrderItem.objects.create(order=order, **item_data)
return order
and finally, a views.py
file
import stripe
from django.conf import settings # get secret key
from rest_framework import status, authentication, permissions
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.response import Response
from .serializers import OrderSerializer
@api_view(['POST'])
@authentication_classes([authentication.TokenAuthentication])
@permission_classes([permissions.IsAuthenticated])
def checkout(request):
serializer = OrderSerializer(data=request.data)
if serializer.is_valid():
stripe.api_key = settings.STRIPE_SECRET_KEY
paid_amount = sum(item.get('quantity') * item.get('product').price for item in serializer.validated_data['items'])
charge = stripe.Charge.create(
amount=int(paid_amount * 100),
currency='USD',
description='Charge from Djackets',
source=serializer.validated_data['stripe_token']
)
serializer.save(user=request.user, paid_amount=paid_amount)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Now trying to post to checkout
gives the 500 response with the following error trace:
Traceback (most recent call last):
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendsutils.py", line 89, in _execute
return self.cursor.execute(sql, params)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendssqlite3base.py", line 477, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: table order_order has no column named paid_amount
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangocorehandlersexception.py", line 55, in inner
response = get_response(request)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangocorehandlersbase.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangoviewsdecoratorscsrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangoviewsgenericbase.py", line 84, in view
return self.dispatch(request, *args, **kwargs)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesrest_frameworkviews.py", line 509, in dispatch
response = self.handle_exception(exc)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesrest_frameworkviews.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesrest_frameworkviews.py", line 480, in raise_uncaught_exception
raise exc
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesrest_frameworkviews.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesrest_frameworkdecorators.py", line 50, in handler
return func(*args, **kwargs)
File "C:Larrydjango-vue-tutorialdjackets_djangoorderviews.py", line 35, in checkout
serializer.save(user=request.user, paid_amount=paid_amount)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesrest_frameworkserializers.py", line 212, in save
self.instance = self.create(validated_data)
File "C:Larrydjango-vue-tutorialdjackets_djangoorderserializers.py", line 37, in create
order = Order.objects.create(**validated_data)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbmodelsmanager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbmodelsquery.py", line 514, in create
obj.save(force_insert=True, using=self.db)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbmodelsbase.py", line 806, in save
self.save_base(
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbmodelsbase.py", line 857, in save_base
updated = self._save_table(
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbmodelssqlcompiler.py", line 1621, in execute_sql
cursor.execute(sql, params)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendsutils.py", line 103, in execute
return super().execute(sql, params)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendsutils.py", line 67, in execute
return self._execute_with_wrappers(
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendsutils.py", line 80, in _execute_with_wrappers
return executor(sql, params, many, context)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendsutils.py", line 84, in _execute
with self.db.wrap_database_errors:
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbutils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendsutils.py", line 89, in _execute
return self.cursor.execute(sql, params)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendssqlite3base.py", line 477, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: table order_order has no column named paid_amount[27/Jul/2022 12:34:17] "POST /api/v1/checkout/ HTTP/1.1" 500 206511
This code originates from a Youtube tutorial that does not explain a whole lot of what is going on. My question is: How to resolve this error?
Thanks in advance!
Answers:
As the error message says, you don’t have paid_amount
column in the order_order
table. If you changed the DB model definition, you need to make a migration and apply it first.
python manage.py makemigrations && python manage.py migrate
So as stated in the comments running:
python manage.py makemigrations
and python manage.py migrate
did not resolve my problem. It simple gives back that there are no migrations.
I did solve the problem by, similar to switching the on/off button, commenting out the paid_amount
column on my model and doing the proper migrations. Then, I uncommented the paid_amount
column did the migrations and then it suddenly worked. I did not change anything to the code so I have no idea why he gave back an error in the first place.
Thanks to all who tried to help, kind of feel bad since in the end a single on/off switch (to the order table) did the trick. But as I said, I’m still learning.
I have the following straightforward setup: a folder order
with a models.py
file,
from django.contrib.auth.models import User
from django.db import models
from product.models import Product
class Order(models.Model):
user = models.ForeignKey(User, related_name='orders', on_delete=models.CASCADE)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
email = models.CharField(max_length=100)
address = models.CharField(max_length=100)
zipcode = models.CharField(max_length=100)
place = models.CharField(max_length=100)
phone = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
paid_amount = models.DecimalField(max_digits=8, decimal_places=2, blank=True, null=True)
stripe_token = models.CharField(max_length=100)
class Meta:
ordering = ['-created_at',]
def __str__(self):
return self.first_name
class OrderItem(models.Model):
order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
product = models.ForeignKey(Product, related_name='items', on_delete=models.CASCADE)
price = models.DecimalField(max_digits=8, decimal_places=2)
quantity = models.IntegerField(default=1)
def __str__(self):
return '%s' % self.id
a serializers.py
file
from rest_framework import serializers
from .models import Order, OrderItem
class OrderItemSerializer(serializers.ModelSerializer):
class Meta:
model = OrderItem
fields = [
"price",
"product",
"quantity",
]
class OrderSerializer(serializers.ModelSerializer):
items = OrderItemSerializer(many=True)
class Meta:
model = Order
fields = [
"id",
"first_name",
"last_name",
"email",
"address",
"zipcode",
"place",
"phone",
"stripe_token",
"items",
]
def create(self, validated_data):
items_data = validated_data.pop('items')
order = Order.objects.create(**validated_data)
for item_data in items_data:
OrderItem.objects.create(order=order, **item_data)
return order
and finally, a views.py
file
import stripe
from django.conf import settings # get secret key
from rest_framework import status, authentication, permissions
from rest_framework.decorators import api_view, authentication_classes, permission_classes
from rest_framework.response import Response
from .serializers import OrderSerializer
@api_view(['POST'])
@authentication_classes([authentication.TokenAuthentication])
@permission_classes([permissions.IsAuthenticated])
def checkout(request):
serializer = OrderSerializer(data=request.data)
if serializer.is_valid():
stripe.api_key = settings.STRIPE_SECRET_KEY
paid_amount = sum(item.get('quantity') * item.get('product').price for item in serializer.validated_data['items'])
charge = stripe.Charge.create(
amount=int(paid_amount * 100),
currency='USD',
description='Charge from Djackets',
source=serializer.validated_data['stripe_token']
)
serializer.save(user=request.user, paid_amount=paid_amount)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Now trying to post to checkout
gives the 500 response with the following error trace:
Traceback (most recent call last):
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendsutils.py", line 89, in _execute
return self.cursor.execute(sql, params)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendssqlite3base.py", line 477, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: table order_order has no column named paid_amount
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangocorehandlersexception.py", line 55, in inner
response = get_response(request)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangocorehandlersbase.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangoviewsdecoratorscsrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangoviewsgenericbase.py", line 84, in view
return self.dispatch(request, *args, **kwargs)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesrest_frameworkviews.py", line 509, in dispatch
response = self.handle_exception(exc)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesrest_frameworkviews.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesrest_frameworkviews.py", line 480, in raise_uncaught_exception
raise exc
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesrest_frameworkviews.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesrest_frameworkdecorators.py", line 50, in handler
return func(*args, **kwargs)
File "C:Larrydjango-vue-tutorialdjackets_djangoorderviews.py", line 35, in checkout
serializer.save(user=request.user, paid_amount=paid_amount)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesrest_frameworkserializers.py", line 212, in save
self.instance = self.create(validated_data)
File "C:Larrydjango-vue-tutorialdjackets_djangoorderserializers.py", line 37, in create
order = Order.objects.create(**validated_data)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbmodelsmanager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbmodelsquery.py", line 514, in create
obj.save(force_insert=True, using=self.db)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbmodelsbase.py", line 806, in save
self.save_base(
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbmodelsbase.py", line 857, in save_base
updated = self._save_table(
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbmodelssqlcompiler.py", line 1621, in execute_sql
cursor.execute(sql, params)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendsutils.py", line 103, in execute
return super().execute(sql, params)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendsutils.py", line 67, in execute
return self._execute_with_wrappers(
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendsutils.py", line 80, in _execute_with_wrappers
return executor(sql, params, many, context)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendsutils.py", line 84, in _execute
with self.db.wrap_database_errors:
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbutils.py", line 91, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendsutils.py", line 89, in _execute
return self.cursor.execute(sql, params)
File "C:Larrydjango-vue-tutorialmyenvlibsite-packagesdjangodbbackendssqlite3base.py", line 477, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: table order_order has no column named paid_amount[27/Jul/2022 12:34:17] "POST /api/v1/checkout/ HTTP/1.1" 500 206511
This code originates from a Youtube tutorial that does not explain a whole lot of what is going on. My question is: How to resolve this error?
Thanks in advance!
As the error message says, you don’t have paid_amount
column in the order_order
table. If you changed the DB model definition, you need to make a migration and apply it first.
python manage.py makemigrations && python manage.py migrate
So as stated in the comments running:
python manage.py makemigrations
and python manage.py migrate
did not resolve my problem. It simple gives back that there are no migrations.
I did solve the problem by, similar to switching the on/off button, commenting out the paid_amount
column on my model and doing the proper migrations. Then, I uncommented the paid_amount
column did the migrations and then it suddenly worked. I did not change anything to the code so I have no idea why he gave back an error in the first place.
Thanks to all who tried to help, kind of feel bad since in the end a single on/off switch (to the order table) did the trick. But as I said, I’m still learning.