Kemil Belcaries
Kemil Belcaries

Reputation: 23

RelatedObjectDoesNotExist?

can someone help me to understand want seam to be the problem I Create a model in a e-comers website.

models:

    class Customer (models.Model):
    user = models.OneToOneField(
        User, on_delete=models.CASCADE, null=True, blank=True)
    name = models.CharField(null=True, max_length=200)
    email = models.CharField(null=True, max_length=200)

    def __str__(self):
        return self.name

then in views i add it to the cart:

def cart(request):
    if request.user.is_authenticated:
        customer = request.user.customer
        order, created = Order.objects.get_or_create(
            customer=customer, complete=False)
        items = order.orderitem_set.all()
    else:
        items = []

    context = {'items': items}
    return render(request, 'ecomeres/cart.html', context)

Upvotes: 1

Views: 3107

Answers (1)

user8193706
user8193706

Reputation: 2425

A OneToOneField actually is a ForeignKey field with a unique=True constraint and a OneToOneField field does not mean that the referenced model always has customer object(in your case). This is why in some case if user.customer for some user not exists then it raises an RelatedObjectDoesNotExist.

So you have to either use try-except and raise exception if object does not exists.

In views.py

from django.core.exceptions import ObjectDoesNotExist

def cart(request):
    try:
        if request.user.is_authenticated:
            customer = request.user.customer
            order, created = Order.objects.get_or_create(
            customer=customer, complete=False)
            items = order.orderitem_set.all()
        else:
            items = []

        context = {'items': items}
        return render(request, 'ecomeres/cart.html', context)
    except ObjectDoesNotExist:
        # hanlde your case when model object does not exist.
    else:
        # this block is excuted only if try except don't raise exception

Or you can also user Python's hasattr() method.

def cart(request):
    if request.user.is_authenticated:
        if hasattr(request.user, 'customer')
            customer = request.user.customer
            order, created = Order.objects.get_or_create(
            customer=customer, complete=False)
            items = order.orderitem_set.all()
        else:
            # handle if request.user has no customer
    else:
        items = []

    context = {'items': items}
    return render(request, 'ecomeres/cart.html', context)

You can see more details about OneToOneField in official documentation where you will get to know about both ObjectDoesNotExist and hasattr

Upvotes: 3

Related Questions