"detail": "Учетные данные для аутентификации не были предоставлены." при попытке получить доступ к представлению списка от имени администратора. REST-фреймворк Django
У меня есть простое представление, которое я построил с помощью фреймворка Django REST:
class ProductListCreateAPIView(
StaffEditorPermissionMixin,
generics.ListCreateAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
def perform_create(self, serializer):
print(serializer.validated_data)
name = serializer.validated_data.get('name')
description = serializer.validated_data.get('description') or None
if description is None:
description = name
serializer.save(description=description)
здесь StaffEditorPermissionMixin:
class StaffEditorPermissionMixin():
permission_classes = [permissions.IsAdminUser, IsStaffEditorPermission]
и вот ProductSerializer:
class ProductSerializer(serializers.ModelSerializer):
edit_url = serializers.SerializerMethodField(read_only=True)
url = serializers.HyperlinkedIdentityField(
view_name='product-details',
lookup_field='pk',
)
class Meta:
model = Product
fields = [
'url',
'edit_url',
'name',
'description',
'price',
'sale_price',
]
def get_edit_url(self, obj):
# return f"/api/v2/products/{obj.pk}/"
request = self.context.get('request')
if request is None:
return None
return reverse("product-edit", kwargs={"pk": obj.pk}, request=request)
и на всякий случай вот products.url:
from django.urls import path
from . import views
urlpatterns = [
path('', views.ProductListCreateAPIView.as_view(), name='product-list'),
path('<int:pk>/update/', views.ProductUpdateAPIView.as_view(), name='product-edit'),
path('<int:pk>/delete/', views.ProductDestroyAPIView.as_view()),
path('<int:pk>/', views.ProductDetailAPIView.as_view(), name='product-details'),
]
и на всякий случай вот исходник urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('api.urls')),
path('api/products/', include('product.urls')),
path('api/v2/', include('rest_practice.routers')),
]
поэтому, когда я вхожу как администратор на http://127.0.0.1:8000/admin/ и перехожу на http://127.0.0.1:8000/api/products/, я не могу получить доступ к списку товаров и получению
HTTP 401 Unauthorized
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
WWW-Authenticate: Bearer
{
"detail": "Authentication credentials were not provided."
}
Так что я не знаю, почему аутентификация не работает, поэтому любая помощь будет оценена по достоинству
По-моему, в вопросе немного неясно, имеется ли в виду собственная админ-панель Django или ваша собственная, которая вызывает эту конечную точку. Это происходит потому, что при переходе на эту страницу из админки в запрос не включается токен пользователя.
При этом я думаю, что лучше отделить ListCreateAPIView от страниц администрирования (если вы говорите о собственных страницах администрирования Django), чтобы представление было логикой, обслуживающей вызовы API. Для этого достаточно изменить файл admin.py в папке app следующим образом:
from django.contrib import admin
from .models import Product
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_filter = ['some_column',...]
list_display = [...]
Надеюсь, это поможет.
Я забыл изменить DEFAULT_AUTHENTICATION CLASSES, где у меня было установлено вот так
auth_classes = [
"rest_framework.authentication.SessionAuthentication",
"api.authentication.TokenAuthentication",
]
if DEBUG:
auth_classes = ["api.authentication.TokenAuthentication"]
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": auth_classes,
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticatedOrReadOnly",
"rest_framework.permissions.IsAdminUser", # ONLY GET METHODS
],
}
там, где должно быть примерно так:
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.SessionAuthentication",
"api.authentication.TokenAuthentication",
],
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticatedOrReadOnly",
"rest_framework.permissions.IsAdminUser", # ONLY GET METHODS
],
}