Reputation: 9885
I am very new to Django so it is hard for me to understand what information is most relevant to try and find the answer to my question.
I followed a tutorial to learn Django. The class creates a shopping cart. I have a problem where I can not add items to the shopping cart or remove them. The main thing that looks suspicious to me is that in the database when I look at a cart there is a drop down to select book but instead of the name of the book it says Book Object
. I believe this is the problem but I am not sure how to troubleshoot it.
I am starting to think maybe this problem is the difference in versions. The tutorial is using a later version. I am using
python 2.7.10 django 1.9.4
I assume this comes down to my models and my view
URL to add to cart and remove
url(r'^add/(\d+)', views.add_to_cart, name='add_to_cart'),
url(r'^remove/(\d+)', views.remove_from_cart, name='remove_from_cart'),
Here is the model for Cart and BookOrder
from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
class Author(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
def __unicode__(self):
return "%s, %s" % (self.last_name, self.first_name)
def cover_upload_path(instance,filename):
return '/'.join(['books',str(instance.id),filename])
class Book(models.Model):
title = models.CharField(max_length=200)
author = models.ForeignKey(Author)
description = models.TextField()
publish_date = models.DateField(default=timezone.now)
price = models.DecimalField(decimal_places=2, max_digits=8)
stock = models.IntegerField(default=0)
cover_image = models.ImageField(upload_to=cover_upload_path, default='books/empty_cover.jpg')
class Review(models.Model):
book = models.ForeignKey(Book)
user = models.ForeignKey(User)
publish_date = models.DateField(default=timezone.now)
text = models.TextField()
latitude= models.FloatField(max_length=20, default="37.41920")
longitude= models.FloatField(max_length=20, default="122.8574")
class Cart(models.Model):
user = models.ForeignKey(User)
active = models.BooleanField(default=True)
order_date = models.DateField(null=True)
payment_type = models.CharField(max_length=100, null=True)
payment_id = models.CharField(max_length=100, null=True)
def add_to_cart(self, book_id):
book = Book.objects.get(pk=book_id)
try:
preexisting_order = BookOrder.objects.get(book=book, cart=self)
preexisting_order.quantity += 1
preexisting_order.save()
except BookOrder.DoesNotExist:
new_order = BookOrder.objects.create(
book=book,
cart=self,
quantity=1
)
new_order.save()
def remove_from_cart(self, book_id):
book = Book.objects.get(pk=book_id)
try:
preexisting_order = BookOrder.objects.get(book=book, cart=self)
if preexisting_order.quantity > 1:
preexisting_order.quantity -= 1
preexisting_order.save()
else:
preexisting_order.delete()
except BookOrder.DoesNotExist:
pass
class BookOrder(models.Model):
book = models.ForeignKey(Book)
cart = models.ForeignKey(Cart)
quantity = models.IntegerField()
And here is the view for adding and removing from cart.
def add_to_cart(request,book_id):
if request.user.is_authenticated():
try:
book = Book.objects.get(pk=book_id)
except ObjectDoesNotExist:
pass
else :
try:
cart = Cart.objects.get(user = request.user, active = True)
except ObjectDoesNotExist:
cart = Cart.objects.create(user = request.user)
cart.save()
cart.add_to_cart(book_id)
return redirect('cart')
else:
return redirect('index')
def remove_from_cart(request, book_id):
if request.user.is_authenticated():
try:
book = Book.objects.get(pk = book_id)
except ObjectDoesNotExist:
pass
else:
cart = Cart.objects.get(user = request.user, active = True)
cart.remove_from_cart(book_id)
return redirect('cart')
else:
return redirect('index')
Upvotes: 2
Views: 1260
Reputation: 8250
For being able to see object names instead of seeing Model object
, you need to define __unicode__
method in your model.
For your cart model:
class Cart(models.Model):
...
[fields]
...
def __unicode__(self):
return "%s's cart" % self.user.username
By defining this, you'll be able to see "username's cart"
For BookOrder Model
class BookOrder(models.Model):
def __unicode__(self):
return self.book.name or self.book.title
By defining this, you'll be able to see the book name like "My Book name".
Upvotes: 1
Reputation: 53386
Add __str__()
or __unicode__()
method in your models. This method is called whenever string representation of an object is required e.g. as you seeing while displaying as a choice in dropdown menu.
You can return any string as it suits your.
Sample:
class Cart(models.Model):
...
def __str__(self,):
return str(self.id)
#OR
return str(self.user)+str(self.id)
Upvotes: 1