#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.