Ошибка атрибута: объект «кортеж» не имеет атрибута «продукт»

#python #django #django-rest-framework

Вопрос:

Когда я перейду по URL:http://127.0.0.1:8000/AddToCart/1/ , он должен добавить товар в корзину. Но он показывает >ошибку атрибута: объект «кортеж» не имеет атрибута «продукт».

Может быть, я совершил ошибку.

models.py:

 class Cart(models.Model):
    id = models.AutoField(primary_key=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
    session_key = models.CharField(max_length=200, blank=True)
    product = models.ManyToManyField(Product, related_name='product_items')
 

views.py:

 @api_view(['GET'])
def addToCart(request, pk):
    product = Product.objects.get(id=pk)
    if request.user.is_authenticated: #user is authenticated
        mycart = Cart.objects.get_or_create(user=request.user)
        mycart.product.add(product) # <--- here is the problem
    else:
        print(request.session.session_key)

    return Response({'response':'ok'})
 

urls.py:
path('addToCart/<str:pk>/', views.addToCart, name='addToCart'),

Что мне нужно изменить, чтобы добавить товар в корзину?

Ответ №1:

get_or_create(…) [Django-doc] возвращает 2-кортеж, в качестве первого элемента Cart которого указан объект, а в качестве второго-a bool , который определяет, был ли создан объект.

Таким образом, вы должны реализовать это с помощью:

 from django.shortcuts import get_object_or_404

@api_view(['GET'])
def addToCart(request, pk):
    product = get_object_or_404(Product, pk=pk)
    if request.user.is_authenticated: #user is authenticated
        #     ↓ unpack the 2-tuple
        mycart, __ = Cart.objects.get_or_create(user=request.user)
        mycart.product.add(product)
    else:
        print(request.session.session_key)

    return Response({'response':'ok'}) 

Примечание: Часто лучше использовать get_object_or_404(…) [Django-doc],
а затем использовать .get(…) [Django-doc] напрямую. В случае, если объект не существует,
например, потому, что пользователь сам изменил URL-адрес, get_object_or_404(…) это приведет к возвращению ответа HTTP 404 «Не найден«, в то время как использование
.get(…) приведет к ошибке сервера HTTP 500.


Примечание: Раздел 9 протокола HTTP указывает, что такие запросы, как GET и HEAD, не должны иметь побочных эффектов, поэтому вам не следует изменять сущности с помощью таких запросов. Обычно для этого используются запросы на публикацию, РАЗМЕЩЕНИЕ, ИСПРАВЛЕНИЕ и УДАЛЕНИЕ. В этом случае вы делаете небольшой <form> запрос, который вызовет запрос POST, или используете несколько вызовов AJAX.