A
A
Alexander Morozov2020-05-19 21:22:47
Django
Alexander Morozov, 2020-05-19 21:22:47

How to solve RelatedObjectDoesNotExist error in Django?

I am writing an online store based on YouTube videos.

The project has two applications - "accounts" and "store".

At first I made a registration and authorization system, everything worked as it should, but now it throws out the error “RelatedObjectDoesNotExist at / - User has no customer.” after I try to log into the newly registered account.

Traceback: - swears at line 14 in store/views.py –> customer = request.user.customer

RelatedObjectDoesNotExist at /
User has no customer.
Request Method:	GET
Request URL:	http://127.0.0.1:8000/
Django Version:	3.0.6
Exception Type:	RelatedObjectDoesNotExist
Exception Value:	
User has no customer.
Exception Location:	/Users//PycharmProjects/app/venv/lib/python3.8/site-packages/django/db/models/fields/related_descriptors.py in __get__, line 420
Python Executable:	/Users//PycharmProjects/app/venv/bin/python
Python Version:	3.8.1


the code:
store/models.py
from django.db import models

from django.contrib.auth.models import User



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

    def __str__(self):
        return self.name



class Product(models.Model):
    name = models.CharField(max_length=100, null=True)
    price = models.FloatField()
    digital = models.BooleanField(default=False, null=True, blank=False)
    image = models.ImageField(null=True, blank=True)

    def __str__(self):
        return self.name

    @property
    def imageURL(self):
        try:
            url = self.image.url
        except:
            url = ''
        return url



class Order(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True, blank=True)
    date_ordered = models.DateTimeField(auto_now_add=True)
    complete = models.BooleanField(default=False)
    transaction_id = models.CharField(max_length=100, null=True)

    def __str__(self):
        return str(self.id)

    # подсчитываем количество абсолютно всех товаров в корзине
    @property
    def get_cart_total(self):
        orderitems = self.orderitem_set.all()
        total = sum([item.get_total for item in orderitems])
        return total

    # общее количество всех товаров в корзине
    @property
    def get_cart_items(self):
        orderitems = self.orderitem_set.all()
        total = sum([item.quantity for item in orderitems])
        return total




class OrderItem(models.Model):
    product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
    order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
    quantity = models.IntegerField(default=0, null=True, blank=True)
    date_added = models.DateTimeField(auto_now_add=True)

    # подсчитываем количество одинаковых товаров (цену умножаем на количество)
    # первым высчитывается значение этого свойсва, а затем в class Order
    @property
    def get_total(self):
        total = self.product.price * self.quantity
        return total



class ShippingAddress(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
    order = models.ForeignKey(Order, on_delete=models.SET_NULL, blank=True, null=True)
    address = models.CharField(max_length=200, null=True)
    city = models.CharField(max_length=200, null=True)
    state = models.CharField(max_length=200, null=True)
    zipcode = models.CharField(max_length=200, null=True)
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.address


store/views.py
from django.shortcuts import render
from django.http import JsonResponse
import json

from .models import *



def store(request):

    # скопировано из checkout -----anti DRY-----↓↓↓↓↓
    # отображение и обновление числа товаров в span возле корзины. {{cartItems}} указываем в html
    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()
        cartItems = order.get_cart_items        # подсчёт и отображение к-ва товаров возле корзины
    else:
        items = []
        order = {'get_cart_total': 0, 'get_cart_items': 0}
        cartItems = order['get_cart_items']     # подсчёт и отображение к-ва товаров возле корзины
    # скопировано из checkout -----anti DRY-----↑↑↑↑↑

    products = Product.objects.all()
    context = {'products': products, 'cartItems': cartItems}
    return render(request, 'store/store.html', context)



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()
        cartItems = order.get_cart_items        # подсчёт и отображение к-ва товаров возле корзины
    else:
        items = []
        order = {'get_cart_total': 0, 'get_cart_items': 0}
        cartItems = order['get_cart_items']     # подсчёт и отображение к-ва товаров возле корзины

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




def checkout(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()
        cartItems = order.get_cart_items        # подсчёт и отображение к-ва товаров возле корзины
    else:
        items = []
        order = {'get_cart_total': 0, 'get_cart_items': 0}
        cartItems = order['get_cart_items']     # подсчёт и отображение к-ва товаров возле корзины

    context = {'items': items, 'order': order, 'cartItems': cartItems}
    return render(request, 'store/checkout.html', context)



def update_item(request):
    data = json.loads(request.body)
    productId = data['productId']
    action = data['action']

    print('productId:', productId)
    print('Action:', action)

    customer = request.user.customer
    product = Product.objects.get(id=productId)
    order, created = Order.objects.get_or_create(customer=customer, complete=False)

    orderItem, created = OrderItem.objects.get_or_create(order=order, product=product)

    if action == 'add':
        orderItem.quantity = (orderItem.quantity +1)
    elif action == 'remove':
        orderItem.quantity = (orderItem.quantity - 1)

    orderItem.save()

    if orderItem.quantity <= 0:
        orderItem.delete()

    return JsonResponse('Item was added', safe=False)



def contacts(request):
    if request.user.is_authenticated:
        customer = request.user.customer
        order, created = Order.objects.get_or_create(customer=customer, complete=False)
        cartItems = order.get_cart_items        # подсчёт и отображение к-ва товаров возле корзины
    else:
        order = {'get_cart_total': 0, 'get_cart_items': 0}
        cartItems = order['get_cart_items']     # подсчёт и отображение к-ва товаров возле корзины

    context = {'order': order,'cartItems': cartItems}
    return render(request, 'store/contact.html', context)


accounts/views.py
from django.shortcuts import render, redirect
from . forms import CreateUserForm
from django.contrib import messages
from django.contrib.auth import authenticate, login, logout
from store.views import store
# from django.forms import inlineformset_factory
# from django.contrib.auth.forms import UserCreationForm



def register_page(request):
    if request.user.is_authenticated:
        return redirect(store)
    else:
        form = CreateUserForm()
        if request.method == 'POST':
            form = CreateUserForm(request.POST)
            if form.is_valid():
                form.save()

                user = form.cleaned_data.get('username')
                messages.success(request, 'Account was created for ' + user)
                return redirect('accounts:login')

        context = {'form': form}
        return render(request, 'accounts/register.html', context)



def login_page(request):
    if request.user.is_authenticated:
        return redirect(store)
    else:
        if request.method == 'POST':
            username = request.POST.get('username')
            password = request.POST.get('password')
            user = authenticate(request, username = username, password = password)

            if user is not None:
                login(request, user)
                return redirect('store')
            else:
                messages.info(request, 'Username OR password is incorrect')

        context = {}
        return render(request, 'accounts/login.html', context)



def logout_user(request):
    logout(request)
    return redirect('accounts:login')


accounts/forms.py
from django.contrib.auth.forms import UserCreationForm

from django.contrib.auth.models import User
from django import forms

class CreateUserForm(UserCreationForm):
    class Meta():
        model = User
        fields = ['username', 'email', 'password1', 'password2']

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question