Почему один и тот же объект выдает ошибку атрибута объекта NoneType в одном экземпляре, а не в других?

Я использую django для настройки функциональности корзины на моем сайте электронной коммерции. Все элементы вводятся как cart_items в таблицу MySQL.

Перед вопросом соответствующий код:

charm = False
if postdata.get('charm_sku'):
    charm_sku = postdata.get('charm_sku','')
    ch = get_object_or_404(Charm, sku=charm_sku)


#get products in cart
cart_products = get_cart_items(request)
product_in_cart = False
# check to see if item is already in cart
for cart_item in cart_products:
    if cart_item.product.id == p.id:
         if charm == True:
              if cart_item.charm.id == ch.id:
                 # update the quantity if found
                 cart_item.augment_quantity(quantity)
                 product_in_cart = True
         else:
             if cart_item.charm.id == "":
                # update the quantity if found
                cart_item.augment_quantity(quantity)
                product_in_cart = True

Изменить: я переработал код, как показано выше, в результате чего ОБА if cart_item.charm.id выдавали ошибку attirbuteerror: 'NoneType' object has no attribute 'id'. В некотором смысле, я думаю, что это улучшило ситуацию, поскольку я подозреваю, что первый, казалось бы, «успешный» был на самом деле первым if charm == True, потерпевшим неудачу, таким образом, никогда не проверяя первый if cart_item.charm.id == ch.id. Остается вопрос: почему это вызывает AttributeError, когда цикл For явно объявляет cart_item, а cart_items явно имеет как столбец очарования, так и идентификатор, назначенный указанным столбцам?

Редактировать 2: Могу ли я не ссылаться на cart_item из вложенных if? Это единственное, о чем я могу думать, но в то же время я чувствую, что должен быть в состоянии, так что, может быть, это неправильно?


person fildred13    schedule 08.04.2013    source источник
comment
Вместо if x ==True: elif x == False: предпочтительнее использовать идиому if x: else:. Если вы ДОЛЖНЫ определить, равны ли они точно True или False, вы должны использовать if x is True: elif x is False: Это потому, что (например) 0 == False верно, а 0 is False ложно.   -  person SethMMorton    schedule 09.04.2013
comment
Нет, у меня нет причин, просто глупая смысловая ошибка в коде прототипа. Исправлю для производства.   -  person fildred13    schedule 09.04.2013


Ответы (2)


NoneType означает, что вместо экземпляра класса у вас фактически есть None. Вероятно, это означает, что присваивание не удалось или вызов функции вернул непредвиденный результат. Ваше назначение cart_item, вероятно, не работает в случае, когда charm == False. Проверьте любой код (назначение или вызов функции), который устанавливает эти две переменные.

person Bill the Lizard    schedule 08.04.2013
comment
Я должен был упомянуть, что ошибка возникает в строке 56, то есть в строке if cart_item.charm.id == "":. Почему эта строка выдает ошибку, а if cart_item.charm.id == ch.id: нет? Я вырезал код до и после предоставленного фрагмента, но не в середине. Я добавлю объявление в начало фрагмента. - person fildred13; 09.04.2013
comment
@ fildred13 Похоже, что cart_item.id присваивается объекту, когда charm == True, но не когда False. - person Bill the Lizard; 09.04.2013
comment
Я расширил код, чтобы включить практически весь def add_to_cart. Я понимаю, что cart_item.id присваивается объекту, когда charm == True, но я просто не понимаю, почему это не так, когда оно ложно. Присваивание происходит прямо здесь, как раз перед условной проверкой charm, значит, что-то в первом условном операторе нарушает присваивание? - person fildred13; 09.04.2013
comment
При дальнейшей обработке на самом деле должно было быть cart_item.charm_id вместо cart_item.charm.id. Этот ответ более или менее привел меня по этому пути, поскольку его рассуждения были правильными, мне просто нужно было выяснить, КАК задание не удалось. - person fildred13; 09.04.2013

Каким-то образом ваше условие charm == False также подразумевает, что cart_item.charm is None. Поскольку вы не проверяете None перед доступом к атрибуту id, возникает исключение.

Я недостаточно знаю об этих переменных и типах объектов, чтобы понять почему, но именно это условие if скрывает вашу проблему.

person Delyan    schedule 08.04.2013