首页 > 其他分享 >DRF案例

DRF案例

时间:2024-04-22 17:36:15浏览次数:22  
标签:return self 案例 import data Response serializer DRF

1 反序列化更新,instance 就传要修改的对象,保证修改完成

def update(self, instance, validated_data):
    publish_id = validated_data.pop('publish')
    author_id = validated_data.pop('author')
    for k in validated_data:
        setattr(instance, k, validated_data[k])
    instance.publish_id = publish_id
    instance.author.set(author_id)
    return instance

2 反序列化保存和更新,字段如下,实现更新和保存

publish_id=serializers.IntegerField(write_only=True) 
authors_l=serializers.ListField(write_only=True)
class BookSerializer(serializers.Serializer):
    publish_id = serializers.IntegerField(write_only=True)
    authors_l = serializers.ListField(write_only=True)

    def create(self, validated_data):
        publish_id = validated_data.pop('publish_id')
        author = validated_data.pop('authors_l')
        book = Book.objects.create(**validated_data, publish_id=publish_id)
        book.author.add(*author)
        return book

    def update(self, instance, validated_data):
        print(validated_data)
        publish_id = validated_data.pop('publish_id')
        author_id = validated_data.pop('authors_l')
        for k in validated_data:
            setattr(instance, k, validated_data[k])
        instance.publish_id = publish_id
        instance.author.set(author_id)
        return instance
def update(self, instance, validated_data):
    print(validated_data) # {'book_name': 'Mona1', 'book_price': 441, 'publish_author': [1, [2, 3]]}
    publish_id = validated_data.get('publish_author')[0]
    author_id = validated_data.get('publish_author')[1]
    validated_data.pop('publish_author')
    for k in validated_data:
        setattr(instance, k, validated_data[k])
        instance.publish_id = publish_id
        instance.author.set(author_id)
        return instance

3 book,publish,author,author_detail

-把所有表的5个接口都写好
-不写author_detail,把author_detail统一放在author中

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': "drftaskbook",
        "USER": "root",
        "PASSWORD": "123456",
        "HOST": "127.0.0.1",
        "PORT": 3307,
        "CHARSET": "utf8mb4",
    }
}

LANGUAGE_CODE = 'zh-hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_L10N = True

USE_TZ = False

INSTALLED_APPS = [
    'book',
    'rest_framework',
]

views.py

from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIView
from .models import Book, Publish, Authors
from .serializer import BookSerializer, PublishSerializer, AuthorsSerializer


# 所有
class BookView(APIView):
    # 查询多条
    def get(self, request):
        obj = Book.objects.all()
        if not obj:
            return Response({'code': 404, "msg": f"没有图书存在"})
        else:
            serializer = BookSerializer(instance=obj, many=True)
            return Response({'code': 200, "msg": "查询所有图书成功", "results": serializer.data})

    # 新增一条
    def post(self, request):
        serializer = BookSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'code': 200, "msg": "新增图书成功"})
        else:
            return Response({'code': 404, "msg": serializer.errors})


# 单个
class BookDetailView(APIView):
    # 查询单个
    def get(self, request, pk):
        obj = Book.objects.filter(pk=pk).first()
        if not obj:
            return Response({'code': 404, "msg": f"图书不存在"})
        else:
            serializer = BookSerializer(instance=obj)
            return Response({'code': 200, "msg": f"查询id为{pk}的图书成功", "results": serializer.data})

    # 删除单个
    def post(self, request, pk):
        obj = Book.objects.filter(pk=pk).first()
        if not obj:
            return Response({'code': 404, "msg": f"图书不存在"})
        else:
            obj.delete()
            return Response({'code': 200, "msg": f"删除id为{pk}的图书成功"})

    # 修改单个
    def put(self, request, pk):
        obj = Book.objects.filter(pk=pk).first()
        serializer = BookSerializer(instance=obj, data=request.data)
        if not obj:
            return Response({'code': 404, "msg": f"图书不存在"})
        if serializer.is_valid():
            serializer.save()
            return Response({'code': 200, "msg": f"修改id为{pk}的图书成功", "result": serializer.data})
        else:
            return Response({'code': 200, "msg": serializer.errors})


class PublishView(APIView):
    # 查询所有出版社
    def get(self, request):
        obj = Publish.objects.all()
        serializer = PublishSerializer(instance=obj, many=True)
        if not obj:
            return Response({'code': 404, "msg": f"没有出版社存在"})
        else:
            return Response({'code': 200, "msg": "查询所有出版社成功", "results": serializer.data})

    # 添加出版社
    def post(self, request):
        serializer = PublishSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'code': 200, "msg": "新增出版社成功", "result": serializer.data})
        else:
            return Response({'code': 200, "msg": serializer.errors})


class PublishDetailView(APIView):
    # 查询单个出版社
    def get(self, request, pk):
        obj = Publish.objects.filter(pk=pk).first()
        if not obj:
            return Response({'code': 404, 'msg': f"id为{pk}的出版社不存在"})
        serializer = PublishSerializer(instance=obj)
        return Response({'code': 200, "msg": f"查询id为{pk}的出版社成功", "results": serializer.data})

    # 删除单个出版社
    def post(self, request, pk):
        obj = Publish.objects.filter(pk=pk).first()
        if not obj:
            return Response({'code': 404, 'msg': f"id为{pk}的出版社不存在"})
        else:
            obj.delete()
            return Response({'code': 200, 'msg': f"删除id为{pk}的出版社成功"})

    # 修改单个出版社
    def put(self, request, pk):
        obj = Publish.objects.filter(pk=pk).first()
        serializer = PublishSerializer(instance=obj, data=request.data)
        if not obj:
            return Response({'code': 404, 'msg': f"id为{pk}的出版社不存在"})
        if serializer.is_valid():
            serializer.save()
            return Response({'code': 200, 'msg': f"修改id为{pk}的出版社成功", 'result': serializer.data})
        else:
            return Response({'code': 404, 'msg': serializer.errors})


class AuthorsView(APIView):
    # 查询所有作者
    def get(self, request):
        obj = Authors.objects.all()
        serializer = AuthorsSerializer(instance=obj, many=True)
        if not obj:
            return Response({'code': 404, "msg": f"没有作者存在"})
        else:
            return Response({'code': 200, "msg": "查询所有作者成功", "results": serializer.data})

    # 添加作者
    def post(self, request):
        serializer = AuthorsSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'code': 200, "msg": "新增作者成功", "result": serializer.data})
        else:
            return Response({'code': 200, "msg": serializer.errors})


class AuthorsDetailView(APIView):
    # 查询单个作者
    def get(self, request, pk):
        obj = Authors.objects.filter(pk=pk).first()
        if not obj:
            return Response({'code': 404, 'msg': f"id为{pk}的作者不存在"})
        serializer = AuthorsSerializer(instance=obj)
        return Response({'code': 200, "msg": f"查询id为{pk}的作者成功", "results": serializer.data})

    # 删除单个作者
    def post(self, request, pk):
        obj = Authors.objects.filter(pk=pk).first()
        if not obj:
            return Response({'code': 404, 'msg': f"id为{pk}的作者不存在"})
        else:
            obj.delete()
            return Response({'code': 200, 'msg': f"删除id为{pk}的作者成功"})

    # 修改单个作者
    def put(self, request, pk):
        obj = Authors.objects.filter(pk=pk).first()
        serializer = AuthorsSerializer(instance=obj, data=request.data)
        if not obj:
            return Response({'code': 404, 'msg': f"id为{pk}的作者不存在"})
        if serializer.is_valid():
            serializer.save()
            return Response({'code': 200, 'msg': f"修改id为{pk}的作者成功", 'result': serializer.data})
        else:
            return Response({'code': 404, 'msg': serializer.errors})

serializer.py

# -*- coding: utf-8 -*-
# author : heart
# blog_url : https://www.cnblogs.com/ssrheart/
# time : 2024/4/12

from rest_framework import serializers
from .models import Book, Publish, Authors, Authors_Detail


class PublishSerializers(serializers.Serializer):
    name = serializers.CharField()
    city = serializers.CharField()


class AuthorsSerializers(serializers.Serializer):
    name = serializers.CharField()
    age = serializers.IntegerField()


class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = Book
        fields = '__all__'

        extra_kwargs = {
            'publish': {'write_only': True},
            'authors': {'write_only': True}
        }

    publish_detail = PublishSerializers(read_only=True, source='publish')
    authors_detail = AuthorsSerializers(read_only=True, source='authors', many=True)


class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model = Publish
        fields = '__all__'


class AuthorDetailSerializer(serializers.Serializer):
    phone = serializers.CharField()
    addr = serializers.CharField()


class AuthorsSerializer(serializers.ModelSerializer):
    class Meta:
        model = Authors
        fields = ['name', 'age', 'author_detail']

    author_detail = AuthorDetailSerializer()

    def create(self, validated_data):
        author_detail = validated_data.pop('author_detail')
        author_detail_obj = Authors_Detail.objects.create(**author_detail)
        data = Authors.objects.create(**validated_data, author_detail=author_detail_obj)
        return data

    def update(self, instance, validated_data):
        author_detail = validated_data.pop('author_detail')
        for k, v in validated_data.items():
            setattr(instance, k, v)
        instance.save()
        for k, v in author_detail.items():
            setattr(instance.author_detail, k, v)
        instance.author_detail.save()
        return instance

models.py

from django.db import models


class Book(models.Model):
    name = models.CharField(max_length=32, db_index=True)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    time = models.DateTimeField(auto_now_add=True, null=True, blank=True)
    publish = models.ForeignKey('Publish', on_delete=models.CASCADE)
    authors = models.ManyToManyField('Authors')


class Publish(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)


class Authors(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='Authors_Detail', on_delete=models.CASCADE)


class Authors_Detail(models.Model):
    phone = models.CharField(max_length=11,null=True,blank=True)
    addr = models.CharField(max_length=32,null=True,blank=True)

urls.py

from django.contrib import admin
from django.urls import path, include
from book.views import BookView, BookDetailView, PublishView, PublishDetailView, AuthorsView, AuthorsDetailView

urlpatterns = [
    path('admin/', admin.site.urls),

    path('bookview/', BookView.as_view()),
    path('bookdetailview/<int:pk>', BookDetailView.as_view()),

    path('publishview/', PublishView.as_view()),
    path('publishdetailview/<int:pk>', PublishDetailView.as_view()),

    path('authorsview/', AuthorsView.as_view()),
    path('authorsdetailview/<int:pk>', AuthorsDetailView.as_view()),
]

4 拓展作业

-找一个混合的后台模板,集成到你项目中
-1 显示用户访问记录
-2 echars---》显示访问客户端类型  饼形图
	-https://echarts.apache.org/examples/zh/editor.html?c=pie-simple
-3 图书增删查改

5 登录注册修改密码接口

#1  创建用户表---》auth 的user表,扩写字段  加个  mobile
	-注册接口:手机号
    	-手机号
        -用户名:要么用手机号,要么随机生成
        -密码:设置默认密码(加密)
        
    -登陆接口:
    	-手机号+密码--》登陆成功
        
    -修改密码接口:
    	-原密码--》校验
        -更新
         ----------------------------
# 2 根据id获取用户详情
# 3 修改用户信息
# 4 查询所有用户
-----写到两个视图中--路由action--》序列化返序列化类可能不一样----  

views.py

from django.shortcuts import render
from rest_framework.viewsets import GenericViewSet
from .serializer import LoginSerializer, PassWordSerializer, RegisterSerializer
from rest_framework.decorators import action
from rest_framework.response import Response
from .models import Users


class User(GenericViewSet):
    queryset = Users.objects.all()
    serializer_class = LoginSerializer
    lookup_field = 'phone'

    def get_serializer_class(self):
        if self.action == 'edit_password':
            return PassWordSerializer
        if self.action == 'register':
            return RegisterSerializer
        else:
            return self.serializer_class

    @action(methods=['POST'], detail=False)
    def login(self, request):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            return Response({'code': 200, 'msg': '登录成功!'})
        else:
            return Response({'code': 404, 'msg': serializer.errors})

    @action(methods=['POST'], detail=False)
    def register(self, request):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'code': 200, 'msg': '注册成功!'})
        else:
            return Response({'code': 404, 'msg': serializer.errors})

    @action(methods=['POST'], detail=False)
    def edit_password(self, request):
        mobile = request.data.get('mobile')
        obj = Users.objects.filter(mobile=mobile).first()
        if not obj:
            return Response({'code': 404, 'msg': '手机号不存在!'})
        serializer = self.get_serializer(instance=obj, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'code': 200, 'msg': '修改成功!'})
        else:
            return Response({'code': 404, 'msg': serializer.errors})

urls.py

from django.contrib import admin
from django.urls import path,include
from app01.views import User
from rest_framework.routers import SimpleRouter

router = SimpleRouter()
router.register('users',User,'users')

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

models.py

from django.db import models
from django.contrib.auth.models import User, AbstractUser


class Users(AbstractUser):
    mobile = models.CharField(max_length=11)

serializer.py

# -*- coding: utf-8 -*-
# author : heart
# blog_url : https://www.cnblogs.com/ssrheart/
# time : 2024/4/16
from rest_framework import serializers
from .models import Users
import re
import hashlib


class LoginSerializer(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = ['mobile', 'password']

    def validate_mobile(self, value):
        # 检查手机号是否符合特定格式或其他条件
        pattern = re.compile(r'^1[3-9]\d{9}$')
        res = Users.objects.filter(mobile=value)
        if not res:
            raise serializers.ValidationError("手机号码不存在!")
        elif not pattern.match(value):
            raise serializers.ValidationError("手机号码格式不正确!")
        return value

    def validate_password(self, attrs):
        md5 = hashlib.md5()
        md5.update(attrs.encode())
        attrs = md5.hexdigest()
        res = Users.objects.filter(password=attrs)
        if not res:
            raise serializers.ValidationError('密码不正确!')
        return attrs


class PassWordSerializer(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = ['mobile', 'password']

    def validate_mobile(self, value):
        # 检查手机号是否符合特定格式或其他条件
        pattern = re.compile(r'^1[3-9]\d{9}$')
        res = Users.objects.filter(mobile=value)
        if not res:
            raise serializers.ValidationError("手机号码不存在!")
        elif not pattern.match(value):
            raise serializers.ValidationError("手机号码格式不正确!")
        return value

    def update(self, instance, validated_data):
        password = validated_data.get('password')
        md5 = hashlib.md5()
        md5.update(password.encode())
        password = md5.hexdigest()
        instance.password = password
        instance.save()
        return instance


class RegisterSerializer(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = ['mobile']

    def validate_mobile(self, value):
        # 检查手机号是否符合特定格式或其他条件
        pattern = re.compile(r'^1[3-9]\d{9}$')
        if not pattern.match(value):
            raise serializers.ValidationError("手机号码格式不正确!")
        return value

    def create(self, validated_data):
        mobile = validated_data.get('mobile')
        password = '123456'
        md5 = hashlib.md5()
        md5.update(password.encode())
        password = md5.hexdigest()
        mobile_last4 = mobile[-4:]
        username = '用户' + mobile_last4 + '_' + password[0:8]
        Users.objects.create(mobile=mobile, username=username, password=password)
        return validated_data

第二版

views.py

import hashlib
import uuid

from django.shortcuts import render
from rest_framework.viewsets import GenericViewSet
from .serializer import LoginSerializer, PassWordSerializer, RegisterSerializer, DetailSerializer
from rest_framework.decorators import action
from rest_framework.response import Response
from .models import Users
from .authentication import LoginAuth


class User(GenericViewSet):
    queryset = Users.objects.all()
    serializer_class = LoginSerializer

    def get_serializer_class(self):
        if self.action == 'edit_password':
            return PassWordSerializer
        if self.action == 'register':
            return RegisterSerializer
        else:
            return self.serializer_class

    @action(methods=['POST'], detail=False)
    def login(self, request):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'code': 200, 'msg': '登录成功!'})
        else:
            return Response({'code': 404, 'msg': serializer.errors})

    @action(methods=['POST'], detail=False)
    def register(self, request):
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'code': 200, 'msg': '注册成功!'})
        else:
            return Response({'code': 404, 'msg': serializer.errors})

    @action(methods=['PUT'], detail=False)
    def edit_password(self, request):
        mobile = request.data.get('mobile')
        obj = Users.objects.filter(mobile=mobile).first()
        if not obj:
            return Response({'code': 404, 'msg': '手机号不存在!'})
        serializer = self.get_serializer(instance=obj, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({'code': 200, 'msg': '修改成功!'})
        else:
            return Response({'code': 404, 'msg': serializer.errors})


# 2 根据id获取用户详情
# 3 修改用户信息
# 4 查询所有用户

from rest_framework.mixins import RetrieveModelMixin, UpdateModelMixin, ListModelMixin


class UserDetail(GenericViewSet, RetrieveModelMixin, UpdateModelMixin, ListModelMixin):
    queryset = Users.objects.all()
    serializer_class = DetailSerializer
    authentication_classes = [LoginAuth]

serializer.py

# -*- coding: utf-8 -*-
# author : heart
# blog_url : https://www.cnblogs.com/ssrheart/
# time : 2024/4/16
import uuid

from rest_framework import serializers
from .models import Users, UserToken
import re
import hashlib

from rest_framework.exceptions import ValidationError


class LoginSerializer(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = ['mobile', 'password']

    def md5hex(self, data):
        data = str(data)
        md5 = hashlib.md5()
        md5.update(data.encode())
        return md5.hexdigest()

    def validate_mobile(self, value):
        # 检查手机号是否符合特定格式或其他条件
        pattern = re.compile(r'^1[3-9]\d{9}$')
        res = Users.objects.filter(mobile=value)
        if not res:
            raise serializers.ValidationError("手机号码不存在!")
        elif not pattern.match(value):
            raise serializers.ValidationError("手机号码格式不正确!")
        return value

    def create(self, validated_data):
        mobile = validated_data.get('mobile')
        old_password = validated_data.get('password')
        new_password = self.md5hex(old_password)
        obj = Users.objects.filter(mobile=mobile, password=new_password).first()
        if obj:
            token = str(uuid.uuid4())
            UserToken.objects.update_or_create(defaults={"token": token}, user=obj)
            return validated_data
        else:
            raise ValidationError('密码不正确!')


class PassWordSerializer(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = ['mobile', 'password']

    def validate_mobile(self, value):
        # 检查手机号是否符合特定格式或其他条件
        pattern = re.compile(r'^1[3-9]\d{9}$')
        res = Users.objects.filter(mobile=value)
        if not res:
            raise serializers.ValidationError("手机号码不存在!")
        elif not pattern.match(value):
            raise serializers.ValidationError("手机号码格式不正确!")
        return value

    def update(self, instance, validated_data):
        password = validated_data.get('password')
        md5 = hashlib.md5()
        md5.update(password.encode())
        password = md5.hexdigest()
        instance.password = password
        instance.save()
        return instance


class RegisterSerializer(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = ['mobile']

    def validate_mobile(self, value):
        # 检查手机号是否符合特定格式或其他条件
        pattern = re.compile(r'^1[3-9]\d{9}$')
        if not pattern.match(value):
            raise serializers.ValidationError("手机号码格式不正确!")
        return value

    def create(self, validated_data):
        mobile = validated_data.get('mobile')
        password = '123456'
        md5 = hashlib.md5()
        md5.update(password.encode())
        password = md5.hexdigest()
        mobile_last4 = mobile[-4:]
        username = '用户' + mobile_last4 + '_' + password[0:8]
        Users.objects.create(mobile=mobile, username=username, password=password)
        return validated_data


class DetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = Users
        fields = '__all__'

    def md5hex(self, data):
        data = str(data)
        md5 = hashlib.md5()
        md5.update(data.encode())
        return md5.hexdigest()

    def update(self, instance, validated_data):
        old_password = validated_data.get('password')
        for k, v in validated_data.items():
            setattr(instance, k, v)
        new_password = self.md5hex(old_password)
        instance.password = new_password
        instance.save()
        return instance

urls.py

from django.contrib import admin
from django.urls import path,include
from app01.views import User,UserDetail
from rest_framework.routers import SimpleRouter

router = SimpleRouter()
router.register('users',User,'users')
router.register('userdetail',UserDetail,'userdetail')

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

models.py

from django.db import models
from django.contrib.auth.models import User, AbstractUser


class Users(AbstractUser):
    mobile = models.CharField(max_length=11)


class UserToken(models.Model):
    token = models.CharField(max_length=64)
    user = models.OneToOneField(to='Users', on_delete=models.CASCADE)

authentication.py

# -*- coding: utf-8 -*-
# author : heart
# blog_url : https://www.cnblogs.com/ssrheart/
# time : 2024/4/16
import uuid

from rest_framework.authentication import BaseAuthentication
from .models import Users, UserToken
from rest_framework.response import Response
from rest_framework.exceptions import AuthenticationFailed


class LoginAuth(BaseAuthentication):
    def authenticate(self, request):
        token = request.META.get('HTTP_TOKEN')
        res = UserToken.objects.filter(token=token).first()
        if res:
            user = res.user
            return user, token
        else:
            raise AuthenticationFailed('请先登录!')

6 0417作业图书

# 1 图书的  查询单条,查询所有 
# 2 图书   新增,修改,删除
# 3 普通用户可以  查询单条,查询所有 
# 4 超级用户可以使用所有

# 5 所有接口,一天访问5次,按ip限制

# 6 图书查询所有接口
	-图书名 和 price范围过滤  
    	price_gt=10&price_lt=100
        
        
# 7 可以按价格和名字排序

# 8 查询所有接口,按 偏移分页


# 9 扩展---》继承BaseThrottle 实现频率限制
# -*- coding: utf-8 -*-
# author : heart
# blog_url : https://www.cnblogs.com/ssrheart/
# time : 2024/4/17


from rest_framework.permissions import BasePermission


class BookPermission(BasePermission):
    def has_permission(self, request, view):
        res = request.user.user_type
        res_str = request.user.get_user_type_display()
        if request.user and request.user.is_authenticated:
            if res == 3:
                return True
            elif request.method == 'GET':
                return True
        return False
class BookView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    authentication_classes = [LoginAuth]
    permission_classes = [BookPermission]

    def list(self, request, *args, **kwargs):
        qs = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(instance=qs, many=True)
        return Response({'code': 100, 'msg':'查询所有数据成功','result':serializer.data})
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': [
        'app01.throttling.CommonThrottle'
    ],
}

7 0418 jwt作业

# 1 编写全局异常处理定制统一返回格式
	-打印出错误详细信息(那个视图类报错了)
	-扩展:自定义异常类,前端收到更多错误状态码
    -扩展:研究全局异常处理源码执行流程
# 2 使用coreapi自动生成接口文档
	-postman导出导入接口
    -showdoc编写几个接口
    -扩展:搭建yapi
    -扩展:drf-yasg自动生成接口文档
    
# 3 快速体验jwt

# 4 拓展
	-登陆接口--》签发token
    	-头 header = {'typ': 'JWT', 'alg': 'HS256'}
        -荷载:{当前用户}
        -签名:md5+settings.SECRET_KEY
        -base64  adsfads.asfdasfd.asfda
    -认证:写个认证了
    	. 分成三段
        前两段 签名
        比较新的和第三段,比较成功--》使用荷载--》用户id--》拿到用户
        

异常类

# -*- coding: utf-8 -*-
# author : heart
# blog_url : https://www.cnblogs.com/ssrheart/
# time : 2024/4/18

from rest_framework.views import exception_handler
from rest_framework.response import Response


# 自定义异常类
class PasswordException(Exception):
    def __init__(self, msg):
        self.msg = msg


import time


# 时间,请求方式,请求的地址,客户端ip,用户id
def common_exception_handler(exc, context):
    """
    :param exc:  错误的原因 division by zero
    :param context: 触发错误的各种参数
    {
      'view': <app01.views.testExc object at 0x000002058BF2A740>,
      'args': (), 'kwargs': {},
      'request': <rest_framework.request.Request: GET '/app01/testexc/'>
      }
    """
    request = context.get('request')
    create_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    method = request.method
    addr = request.get_full_path()
    ip = request.META.get('REMOTE_ADDR')
    id = request.user
    view = context.get('view')
    log = [create_time, method, addr, ip, id,view]
    with open('log.log', 'a', encoding='utf-8') as f:
        f.write('\n' + str(log))

    response = exception_handler(exc, context)
    if response:
        if isinstance(response.data, dict):
            error = response.data.get('detail', '系统错误,请联系heartt')
            return Response({"code": 991, 'msg': f"{error}"})
        elif isinstance(response.data, list):
            error = response.data[0]
        else:
            error = '系统错误,请联系heartt'
        return Response({"code": 992, 'msg': f"{error}"})
    else:
        if isinstance(exc, ZeroDivisionError):
            response = Response({"code": 993, 'msg': f"{str(exc)}"})
        elif isinstance(exc, PasswordException):
            response = Response({"code": 994, 'msg': f"密码错误"})
        elif isinstance(exc, Exception):
            response = Response({"code": 995, 'msg': f"{str(exc)}"})
        else:
            response = Response({"code": 999, 'msg': f"{str(exc)}"})
    return response

views.py

from django.shortcuts import render
from rest_framework.viewsets import GenericViewSet
from django.contrib.auth.models import User
from .serializer import UserSerializer
from rest_framework.decorators import action
from rest_framework.response import Response
from django.contrib import auth
import hashlib
import json
import base64
from django.conf import settings
from .Authenticated import UserAuth
from rest_framework.mixins import ListModelMixin


class UserLoginView(GenericViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    authentication_classes = [UserAuth]
    @action(methods=['POST'], detail=False)
    def login(self, request):
        username = request.data.get('username')
        password = request.data.get('password')
        user = auth.authenticate(request, username=username, password=password)
        if user:
            header = {'typ': 'JWT', 'alg': 'HS256'}
            auth.login(request, user)
            obj = User.objects.filter(username=username).first()
            payload = {
                key: getattr(obj, key)
                for key in ['id', 'username', 'is_superuser']
            }
            header_str = json.dumps(header)
            payload_str = json.dumps(payload)
            secret_key = settings.SECRET_KEY
            signature = header_str + payload_str + secret_key
            md5 = hashlib.md5()
            md5.update(signature.encode('utf-8'))
            res = md5.hexdigest()
            header_str_b64 = base64.b64encode(header_str.encode('utf-8'))
            payload_str_b64 = base64.b64encode(payload_str.encode('utf-8'))
            signature_b64 = base64.b64encode(res.encode('utf-8'))
            access_key = header_str_b64 + b'.' + payload_str_b64 + b'.' + signature_b64
        return Response({'code': 100, 'msg': '登录成功!', 'access_key': access_key})


class UserDetailView(GenericViewSet,ListModelMixin):
    def list(self, request, *args, **kwargs):
        return Response({'code': 200, 'msg': f'查询成功,当前用户是{request.user}'})

认证类

# -*- coding: utf-8 -*-
# author : heart
# blog_url : https://www.cnblogs.com/ssrheart/
# time : 2024/4/18
import base64
import hashlib

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from django.conf import settings
import json
from django.contrib.auth.models import User

class UserAuth(BaseAuthentication):
    def authenticate(self, request):
        token = request.META.get('HTTP_TOKEN')
        if token:
            secret_key = settings.SECRET_KEY
            ss = token.split('.')
            header = ss[0]
            payload = ss[1]
            new_access_key = ss[2]
            header_b = base64.b64decode(header)
            payload_b = base64.b64decode(payload)
            header_ab = json.dumps(json.loads(header_b))
            payload_ab = json.dumps(json.loads(payload_b))
            signature = header_ab + payload_ab + secret_key
            md5 = hashlib.md5()
            md5.update(signature.encode('utf-8'))
            res = md5.hexdigest()
            signature_b = base64.b64encode(res.encode('utf-8'))
            if signature_b.decode('utf-8') == new_access_key:
                id = json.loads(payload_b).get('id')
                user_obj = User.objects.filter(pk=id).first()
                return user_obj,new_access_key
        else:
            raise AuthenticationFailed('请先登录!')

标签:return,self,案例,import,data,Response,serializer,DRF
From: https://www.cnblogs.com/ssrheart/p/18150677

相关文章

  • drf中jwt应用
    第一步 在登录类中生成jwtclassLogin(MyException,APIView):defpost(self,request):user_obj=models.UserInfo.objects.filter(**request.data).first()ifnotuser_obj:returnResponse({"code":1001,"msg":"用户......
  • php之性能优化案例
    php是一个很流行的脚本语言,现在很多公司(新浪、优酷、百度、搜狐、淘宝等等)在使用这种语言进行网站开发。这篇文章希望能够提高你的php脚本性能。请记住你的php脚本性能,很多时候依赖于你的php版本、你的webserver环境和你的代码的复杂度。优化你代码中的瓶颈Hoare曾经说过“过早......
  • SpringCloud进行nacos的服务注册和服务管理案例
    SpringCloud服务注册pom.xml<!--SpringCloud服务注册和发现--><dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <version>2.2.8.RELEASE</version>......
  • IfcUnitAssignment案例
    当没有使用实体类型IfcMeasureWithUnit作为属性的数据类型更具体地定义单位时,项目的全局单位分配定义度量值和值的全局单位。 Anexamplewhereaproject’sglobalbasiclength,area,volumeandtimeunitsaredefinedasSIunits:#1=IFCPROJECT(’00ZhrqZYLBcgy$rVVa......
  • DRF之类视图详解介绍
    一、视图基类1、APIView想要使用APIView,需要先导入:fromrest_framework.viewsimportAPIViewAPIView继承了View,同时也进行了升级,APIView是适合前后端分离的,而View是适合前后端不分离的。View并没有对请求进行处理,而APIView会对请求进行处理,将请求体的JSON数据转成......
  • DRF之路由组件
    一、路由的写法1、原始写法(1)介绍是指手动编写路由规则的方式。使用path()函数或re_path()函数来定义路由规则,并将其与对应的视图函数或类关联起来。(2)示例假设有一个名为book的应用,它包含了一个处理图书列表的视图函数book_list,以及一个处理单个图书详情的视图函数book_de......
  • 队列-经典应用案例
    这里来简单举几个经典的场景如"击鼓传花","字符串回文监测"等来加深对队列这个结构的直观认识.单端队列-击鼓传花这里先介绍一种队列的变种叫循环队列,即元素从队首出队后,立即又进行从队尾入队,类似行程了一个圈,与之对应的一个经典游戏就是"击鼓传花",英文叫ho......
  • 【用户案例】数字化转型中的新质生产力:东风日产的RPA实践与启示
    在数字化时代的浪潮中,企业数字化转型已成为不可逆转的趋势。面对工效联动和数字化转型的双重挑战,传统汽车行业急需寻找新的突破点。东风日产,作为一家拥有 1.9万名员工的汽车企业,为我们展示了如何成功实现内部转型东风日产是东风汽车有限公司旗下的重要乘用车板块,致力于以先进......
  • HarmonyOS NEXT应用开发—翻页动效案例
    介绍翻页动效是应用开发中常见的动效场景,常见的有书籍翻页,日历翻页等。本例将介绍如何通过ArkUI提供的显示动画接口animateTo实现翻页的效果。效果图预览使用说明本例通过setInterval函数每秒调用一次翻页动画,实现连续翻页效果。实现思路如图,左右两侧分别代表打开书籍的......
  • textfsm 案例分享
    由于安全需要,需要定期对接入层交换机配置进行合规检查,避免不规范配置存在的漏洞给公司网络带来安全风险。如下案例是通过textfsm提取交换机接口的配置信息,进一步进行检查准入配置是否开启:1、首先看接口下的配置interfaceGigabitEthernet1/0/7descriptionuser_0001switc......