【问题标题】:ValueError at / Cannot query "user5": Must be "Customer" instanceValueError at / Cannot query "user5": must be "Customer" instance
【发布时间】:2021-06-04 09:26:16
【问题描述】:

即使 user5 在用户表中,但是当我登录时它给了我这个消息

ValueError at / Cannot query "user5": must be "Customer" instance.

这是我网站的模型。

此网站还允许您在没有帐户的情况下结帐。

这里是关于代码的更多信息,这显示了完整的堆栈跟踪,我希望现在它更容易理解。

models.py

class Customer(models.Model):
    customer = models.OneToOneField(User, on_delete=models.CASCADE, related_name = 'customer', null=True, blank=True)
    name = models.CharField(max_length= 200, null=True)
    email = models.CharField(max_length=200, null=True)
    date_created = models.DateTimeField(auto_now_add=True, null=True)
    
    def __str__(self):
        return self.name


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

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

    @property
    def shipping(self):
        shipping=False
        orderitems = self.orderitem_set.all()
        for i in orderitems:
            if i.product.digital == False:
                shipping=True
        return shipping
    

    @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

views.py

def store(request):
data = cartData(request)
cartItems = data['cartItems']

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


def cart(request):
    data = cartData(request)
    cartItems = data['cartItems']
    order = data['order']
    items = data['items']

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


def checkout(request):
    data = cartData(request)
    cartItems = data['cartItems']
    order = data['order']
    items = data['items']

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


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

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

    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 added', safe=False)


def processOrder(request, customer):
    transaction_id = datetime.datetime.now().timestamp()
    data = json.loads(request.body)

    if(request.user.is_authenticated):
        customer = request.user.customer
        order, created = Order.objects.get_or_create(customer = customer, complete= False)

    else:
        customer, order = guestOrder(request, data)    

    total = float(data['form']['total'])
    order.transaction_id = transaction_id

    if total==float(order.get_cart_total):
        order.complete = True
    order.save()

    if order.shipping == True:
            ShippingAddress.objects.create(
                customer = customer,
                order = order,
                address = data['shipping']['address'],
                city = data['shipping']['city'],
                state = data['shipping']['state'],
                zipcode = data['shipping']['zipcode'],
            )   

    return JsonResponse('Payment complete!', safe=False)


def registerPage(request):
    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 created successfully for "+user)
            return redirect('login')

    context = {'form': form}
    return render(request, 'store/registration.html', context


def loginPage(request):
    if request.method=="POST":
        username = request.POST.get('username')
        password = request.POST.get('password')        
        user = authenticate(request, username=username, password=password)

        if user:
            login(request, user)
            messages.success(request, "Logged In")
            return redirect('store')
        else:
            messages.error(request, "Invalid Credentials")
            return redirect("login")

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

utils.py

def cookieCart(request):
    try:
        cart = json.loads(request.COOKIES['cart'])
    except:
        cart={}
    print('Cart: ',cart)
    items = []
    order = {'get_cart_total':0, 'get_cart_items':0, 'shipping': False}
    cartItems = order['get_cart_items']
    for i in cart:
        try:
            cartItems += cart[i]['quantity']
            product = Product.objects.get(id=i)
            total = (product.price * cart[i]['quantity'])
            order['get_cart_total'] += total
            order['get_cart_items'] += cart[i]['quantity']
            item = {
                'product':{
                    'id':product.id,
                    'name': product.name,
                    'price': product.price,
                    'imageURL': product.imageURL,
                },
                'quantity': cart[i]['quantity'],
                'get_total' : total
            }
            items.append(item)
            if product.digital == False:
                order['shipping'] = True
        except:
            pass

    return{'cartItems':cartItems, 'order':order, 'items':items}


def cartData(request):
        if request.user.is_authenticated:
            customer = request.user
            order, created = Order.objects.get_or_create(customer = customer, complete= False)
            items = order.orderitem_set.all()
            cartItems = order.get_cart_items
        else:
            cookieData=cookieCart(request)
            cartItems = cookieData['cartItems']
            order = cookieData['order']
            items = cookieData['items']
        return {'cartItems':cartItems, 'order':order, 'items':items}


def guestOrder(request, data):
    print('User not logged in')

    print('COOKIES: ',request.COOKIES)
    name = data['form']['name']
    email = data['form']['email']

    cookieData = cookieCart(request)
    items = cookieData['items']

    customer, created = Customer.objects.get_or_create(
        email = email,
        )
    customer.name = name
    customer.save()

    order = Order.objects.create(
        customer = customer,
        complete = False,
        )

    for item in items:
        product = Product.objects.get(id= item['product']['id'])

        orderItem = OrderItem.objects.create(
            product = product,
            order = order,
            quantity=item['quantity']
            )

    return customer, order 

settings.py

    import os
from django.contrib.messages import constants as messages


MESSAGE_TAGS = {
        messages.DEBUG: 'alert-secondary',
        messages.INFO: 'alert-info',
        messages.SUCCESS: 'alert-success',
        messages.WARNING: 'alert-warning',
        messages.ERROR: 'alert-danger',
 }
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'a=m+1^c$evt6l5$f=(9ea^7n7r#r8rpjdu57&(((8ms(gvx2g('

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'store.apps.StoreConfig',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'GetItNow.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'template')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',                
            ],
        },
    },
]

WSGI_APPLICATION = 'GetItNow.wsgi.application'


# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}


# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/

STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
VENV_PATH = os.path.dirname(BASE_DIR)
STATIC_ROOT = os.path.join(VENV_PATH, 'static_root')

MEDIA_URL = '/images/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/images')

【问题讨论】:

  • 你能包含完整的堆栈跟踪吗?这将有助于确定导致问题的线路。
  • 是的,确定@schillingt 这里是更新后的代码!

标签: python django valueerror


【解决方案1】:

虽然您的代码没有提供实际问题的详细信息。但是从他们那里我可以理解的是,您的 User 表与 Customer 表具有 1to1 关系,并且您允许非注册客户结帐。问题是当您与未注册客户结帐时,用户是匿名的,并且该匿名用户在客户表上没有任何详细信息。所以引发了异常。

您需要做的是简单地更改 Order 模型与 User 表的客户关系,而不是与 Customer 表的关系。如果您更改它,那么如果您对未签名用户使用 Django 默认匿名用户,那么它将自动为未签名用户获取 Django Anonymous 用户,您不必担心用户的客户详细信息。

class Customer(models.Model):
    customer = models.OneToOneField(User, on_delete=models.CASCADE, related_name = 'customer', null=True, blank=True)
    name = models.CharField(max_length= 200, null=True)
    email = models.CharField(max_length=200, null=True)
    date_created = models.DateTimeField(auto_now_add=True, null=True)
    
    def __str__(self):
        return self.name


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

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

【讨论】:

  • 是的,我尝试了您的建议,但问题尚未解决,它说 utils.py 中存在一些问题。它现在给我外键完整性错误
  • 异常是只发生在未签名的用户身上还是也发生在已签名的用户身上?
  • @Varuni 还有一件事您的客户模型客户列名称与相关名称客户相同。请更改其中一个名称。有时它可能会导致问题。
  • 注册用户和未注册用户都会出现问题。
  • @Varuni 你能给我你的 settings.py 文件吗?
猜你喜欢
  • 2020-09-17
  • 2018-02-05
  • 2021-03-26
  • 1970-01-01
  • 2022-09-03
  • 2019-10-30
  • 1970-01-01
  • 2017-08-14
  • 2021-09-27
相关资源
最近更新 更多