Невозможно выполнить POST с помощью ListCreateAPIView
Большое спасибо за помощь.
В настоящее время мы используем Django для создания блога с функциями членства. Я хотел бы позволить только членам клуба публиковать статьи, но я не могу использовать POST, когда я вошел в систему. Если не входить в систему, POST доступен.
Что случилось?
models.py
class Post(models.Model):
title = models.CharField(max_length=100, blank=True, default='')
content = models.TextField(blank=True, default='')
def __str__(self):
return self.title
class Category(models.Model):
name = models.CharField(max_length=100, blank=False, null=True, default='')
posts = models.ManyToManyField(Post, related_name='categories', blank=True)
class Meta:
verbose_name_plural = 'categories'
def __str__(self):
return self.name
serializers.py
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ['id', 'title','content', 'categories']
class CategorySerializer(serializers.ModelSerializer):
name = serializers.CharField(required=False, allow_null=True, allow_blank=True)
posts = PostSerializer(many=True, read_only=True)
new_posts = serializers.PrimaryKeyRelatedField(
queryset=Post.objects.all(), many=True,
write_only=True, required=False)
class Meta:
model = Category
fields = ['id', 'name', 'posts', 'new_posts']
def create(self, validated_data):
category = Category.objects.create()
category.name = validated_data.pop('name', None)
new_posts = validated_data.pop('new_posts', None)
category.posts.set(new_posts)
category.save()
return category
def update(self, instance, validated_data):
instance.name = validated_data.get('name', instance.name)
instance.posts.set(validated_data.get('new_posts', instance.posts))
instance.save()
return instance
views.py
class PostList(generics.ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = serializers.PostSerializer
permission_classes = (IsAdmin,)
# permission_classes = (AllowAny,)
permissions.py
class IsAdmin(permissions.IsAdminUser):
def has_permission(self, request, view):
if request.method in permissions.SAFE_METHODS:
role_slug = None
if not request.user.is_anonymous and request.user.role is not None:
role_slug = request.user.role
if role_slug:
return bool(str(role_slug) == 'admin')
else:
return False
urls.py
urlpatterns = [
path('posts/', views.PostList.as_view()),
]
settins.py
INSTALLED_APPS = [
# ommited
# 3rd party
'rest_framework',
'corsheaders',
'djoser',
# my apps
'blogs.apps.BlogsConfig',
]
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES' : [
'rest_framework.permissions.IsAuthenticated'
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
}
POST запрос с логином и ответом
{
"detail": "You do not have permission to perform this action."
}
Если вы попытаетесь выполнить POST не войдя в систему...
{
"id": 1,
"title": "title ok.",
"content": "content ok.",
}
Проверяя permissions.SAFE_METHODS, кажется, что принимаются только следующие (без POST).
('GET', 'HEAD', 'OPTIONS')
Является ли это спецификацией ListCreateAPIView?
Да, безопасными методами являются ('GET', 'HEAD', 'OPTIONS')
Пожалуйста, проверьте репозиторий GitHub на наличие разрешений rest_framework. https://github.com/encode/django-rest-framework/blob/master/rest_framework/permissions.py
Вы можете переписать класс разрешения на приведенный ниже.:
def has_permission(self, request, view):
if request.method in 'POST':
role_slug = None
if not request.user.is_anonymous and request.user.role is not None:
role_slug = request.user.role
if role_slug:
return bool(str(role_slug) == 'admin')
else:
return False