django serializer中不仅可以定义返回的字段,也可以定义相关重写的方法。
对于不同的数据权限,可以定义不同的数据集feildsets来指向不同的用户拥有的权限。
设置全局权限在setting中:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
}
当然可以继承一个权限类,重写新的权限:
from rest_framework import permissions
class IsStaffEditorPermission(permissions.DjangoModelPermissions):
perms_map = {
'GET': ['%(app_label)s.view_%(model_name)s'],
'OPTIONS': [],
'HEAD': [],
'POST': ['%(app_label)s.add_%(model_name)s'],
'PUT': ['%(app_label)s.change_%(model_name)s'],
'PATCH': ['%(app_label)s.change_%(model_name)s'],
'DELETE': ['%(app_label)s.delete_%(model_name)s'],
}
随后可以指定一个公用permission类:
from rest_framework import permissions
from .permissions import IsStaffEditorPermission
class StaffEditorPermissionMixin():
permission_classes = [permissions.IsAdminUser, IsStaffEditorPermission]
在非全局权限的接口中使用它:
这样做是为了防止过多的同样设置的繁琐
from rest_framework import generics, mixins
from rest_framework.decorators import api_view
from rest_framework.response import Response
# from django.http import Http404
from django.shortcuts import get_object_or_404
from api.mixins import (
StaffEditorPermissionMixin,
UserQuerySetMixin)
from .models import Product
from .serializers import ProductSerializer
class ProductListCreateAPIView(
UserQuerySetMixin,
StaffEditorPermissionMixin,
generics.ListCreateAPIView):
queryset = Product.objects.all()
serializer_class = ProductSerializer
def perform_create(self, serializer):
# serializer.save(user=self.request.user)
title = serializer.validated_data.get('title')
content = serializer.validated_data.get('content') or None
if content is None:
content = title
serializer.save(user=self.request.user, content=content)
同样的,对于字段校验也是一样:
比如声明一个validators.py
from rest_framework import serializers
from rest_framework.validators import UniqueValidator
from .models import Product
def unique_product_title(value):
qs = Product.objects.filter(title__iexact=value)
if qs.exists():
raise serializers.ValidationError(f"{value} is already a product name.")
return value
def validate_title_no_hello(value):
if "hello" in value.lower():
raise serializers.ValidationError(f"{value} is not allowed")
return value
unique_product_title = UniqueValidator(queryset=Product.objects.all(), lookup='iexact')
上面验证title这个字段并不能包括‘hello’字眼,不管大小写。
然后这样使用:
class ProductSerializer(serializers.ModelSerializer):
owner = UserPublicSerializer(source='user', read_only=True)
title = serializers.CharField(validators=[validators.validate_title_no_hello, validators.unique_product_title])
body = serializers.CharField(source='content')
class Meta:
model = Product
fields = [
'owner',
'pk',
'title',
'body',
'price',
'sale_price',
'public',
'path',
'endpoint',
]
def get_my_user_data(self, obj):
return {
"username": obj.user.username
}
def get_edit_url(self, obj):
request = self.context.get('request') # self.request
if request is None:
return None
return reverse("product-edit", kwargs={"pk": obj.pk}, request=request)
想到了继续再更。
标签:title,request,value,django,framework,rest,import From: https://www.cnblogs.com/ukzq/p/17066267.html