Karthik
Karthik

Reputation: 676

None Type Error Attribute

I've been trying to implement a shopping cart on my website based on Django.

Below are the models I used:

class ShoppingCart(models.Model):
    songs = models.ManyToManyField(Song)
    albums = models.ManyToManyField(Album)

class Listener(User):
    name = models.CharField(max_length=200, blank=True, null=True)
    bio = models.TextField(blank=True, null=True)
    cart = models.ForeignKey(ShoppingCart, blank=True, null=True)

Here is the views.py where I get an error saying None Type Object has no attribute songs at request.user.listener.cart.songs.add():

def add_to_cart(request):
    if not request.user.is_authenticated() or not request.method == 'POST':
        return HttpResponse(json.dumps({'success':False}), content_type='application/json')
    typeobj = request.POST.get('type', None)
    obj = request.POST.get('id', None)
    if typeobj is None or obj is None:
        return HttpResponse(json.dumps({'success':False}), content_type='application/json')

    if typeobj == 'album':
        try:
            album = Album.objects.get(pk=obj)
        except ObjectDoesNotExist:
            return HttpResponse(json.dumps({'success':False}), content_type='application/json')
        request.user.listener.cart.albums.add(Album.objects.get(pk=obj))
    else:
        try:
            song = Song.objects.get(pk=obj)
        except ObjectDoesNotExist:
            return HttpResponse(json.dumps({'success':False}), content_type='application/json')
        request.user.listener.cart.songs.add(Song.objects.get(pk=obj))
    return HttpResponse(json.dumps({'success':True}), content_type='application/json')

I checked in the shell and the same error occurs when I try to add a song to the cart. It says cart is a NoneType object and has no attribute songs.

Thanks in advance.

Upvotes: 1

Views: 164

Answers (2)

Rohan
Rohan

Reputation: 53326

  1. I think you should use OneToOne relationship between User and ShoppingCart.

Sample model:

class Listener(User):
   name = models.CharField(max_length=200, blank=True, null=True)
   bio = models.TextField(blank=True, null=True)
   cart = models.OneToOneField(ShoppingCart, blank=True, null=True)
  1. In your view create a cart for user if it does not exists

As

def add_to_cart(request):
    if not request.user.is_authenticated() or not request.method == 'POST':
       return HttpResponse(json.dumps({'success':False}), content_type='application/json')
    typeobj = request.POST.get('type', None)
    obj = request.POST.get('id', None)
    if typeobj is None or obj is None:
        return HttpResponse(json.dumps({'success':False}), content_type='application/json')

    if request.usr.listener.cart == None:
         cart = ShoppingCart()
         cart.save()
         request.usr.listener.cart = cart
         request.usr.listener.save()

    # your code to add items in cart

Upvotes: 1

Burhan Khalid
Burhan Khalid

Reputation: 174624

request.user is an instance of the User object of the currently logged in user.

There is no relation between your Listener model and the User model (even though you inherited from it), so whatever you are trying to do, it won't work. In fact, even if there was a relationship, you'd be seeing these errors because you are not using the object relations correctly.

If you want to track a shopping cart for each user permanently, you need to add a ForeignKey to your ShoppingCart model to point to the User model.

If you just want to track the cart for a session; then use sessions to do so.

It might benefit you from going through the relations section of the documentation, since you aren't using add() correctly either.

Upvotes: 1

Related Questions