首页 > 解决方案 > 只允许在 Django Rest Framework 中编辑和不写入字段

问题描述

所以我正在尝试使用 Django rest 框架创建一个 todo 应用程序,并将我的 models.py 作为...

class Task(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    task = models.CharField(max_length=150)
    date_created = models.DateTimeField(auto_now=True)
    completed = models.BooleanField(default=False)

我想要的是,当用户输入他们的任务时,我希望该completed属性对用户隐藏并自动将其设置为false. 但随后允许用户稍后更改为 true 或 false。

用我目前的serializer.py ..

class TaskSerializer(serializers.ModelSerializer):

    class Meta:
        model = Task
        fields = ('id', 'task', 'date_created', 'completed')
        extra_kwargs = {
            "date_created":{"read_only":True},
            # 'completed':{"read_only":True}
        }

还有我的意见.py...

class ListView(viewsets.ModelViewSet):
    serializer_class = serializers.TaskSerializer
    permission_classes = (IsAuthenticated, permissions.ViewOwnTask)

    def get_queryset(self):
        return Task.objects.filter(user=self.request.user)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

在我的 serializer.py 中,注释代码'completed':{"read_only":True}允许用户在上传时编辑字段并在该字段上写入,如图所示这里

但是,当我取消注释该'completed':{"read_only":True}字段时,写入已完成字段的选项会消失,但是我不允许编辑该字段。

是否有任何内容,例如{"edit_only":True},只允许用户编辑该字段。如果你明白我的意思。

任何帮助将不胜感激。谢谢!

编辑

我的 urls.py 是...

router = DefaultRouter()
router.register('task', views.ListView, basename='task')


urlpatterns = [
    path('', include(router.urls)),
]

第二次编辑

在此处输入图像描述

嘿@PrakashS 现在我得到了我不想要的这种输出,我只想completed编辑该字段。

标签: pythondjangodjango-rest-framework

解决方案


使用不同的序列化程序来添加和编辑任务:

from rest_framework import serializers
from tasks.models import Task


class TaskSerializer(serializers.ModelSerializer):

    class Meta:
        model = Task
        fields = '__all__'
        extra_kwargs = {
            'completed':{"read_only":True}
        }     

class TaskEditSerializer(serializers.ModelSerializer):

    class Meta:
        model = Task
        fields = '__all__'

在视图中,您可以根据添加或编辑视图选择序列化程序:

from rest_framework.generics import RetrieveUpdateDestroyAPIView, ListCreateAPIView
from rest_framework.permissions import IsAuthenticated
from .models import Task
from .permissions import IsOwnerOrReadOnly
from .serializers import TaskSerializer, TaskEditSerializer


class ListCreateTaskAPIView(ListCreateAPIView):
    serializer_class = TaskSerializer
    queryset = Task.objects.all()
    permission_classes = [IsAuthenticated]

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)


class RetrieveUpdateDestroyTaskAPIView(RetrieveUpdateDestroyAPIView):
    serializer_class = TaskEditSerializer
    queryset = Task.objects.all()
    permission_classes = [IsAuthenticated, IsOwnerOrReadOnly]

urls.py 文件:

from django.urls import path
from . import views


urlpatterns = [
    path('', views.ListCreateTaskAPIView.as_view(), name='get_post_tasks'),
    path('<int:pk>/', views.RetrieveUpdateDestroyTaskAPIView.as_view(), name='get_delete_update_task'),
]

权限.py 文件:

from rest_framework import permissions
from rest_framework.exceptions import PermissionDenied


class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Custom permission to only allow creator of an object to edit it.
    """

    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True

        # Write permissions are only allowed to the creator of the movie
        return obj.user == request.user

推荐阅读