service.py
def add_goods_to_cart(goods_id, user, addend):
goods = Goods.objects.filter(pk=goods_id).first()
if goods:
the_goods_already_in_cart = Cart.objects.filter(user=user, goods=goods, order=None).first()
if the_goods_already_in_cart:
the_goods_already_in_cart.quantity = (the_goods_already_in_cart.quantity + addend)
if the_goods_already_in_cart.quantity == 0:
the_goods_already_in_cart.delete()
else:
the_goods_already_in_cart.save()
else:
Cart.objects.create(user=user, goods=goods, quantity=1)
status = 200
else:
status = 400
return status
views.py
class AddToCart(LoginRequiredMixin,
View):
def post(self, request):
goods_id = request.POST.get('goods_id')
addend = int(request.POST.get('addend'))
assert (addend == 1 or addend == -1)
status = add_goods_to_cart(goods_id, request.user, addend)
if status == 200:
act = "added to cart" if addend > 0 else "removed from cart"
messages.add_message(request, messages.INFO, 'Goods "{}" {}.'.format(goods.name, act))
return redirect(request.META['HTTP_REFERER'])
else:
return HttpResponse("Wrong goods id", status=status)
What troubles me:
Well, anyway, the architecture of this code stinks. Maybe I should return from the service not the status code, but the name of the added goods?
How can I refactor this code?
You don't have to return status code in your service.py to understand what happened in it, there is an also simpler way to return both good's name and a sign of what has happened in service.py by only returning good's name if it existed and None if it not existed. so you can handle status code in your view and also you have the name of that good:
goods = Goods.objects.filter(pk=goods_id).first()
if goods:
the_goods_already_in_cart = Cart.objects.filter(user=user, goods=goods, order=None).first()
if the_goods_already_in_cart:
the_goods_already_in_cart.quantity = (the_goods_already_in_cart.quantity + addend)
if the_goods_already_in_cart.quantity == 0:
the_goods_already_in_cart.delete()
else:
the_goods_already_in_cart.save()
else:
Cart.objects.create(user=user, goods=goods, quantity=1)
return goods.name # Return the name of the added goods
return None # This shows that goods were not found