1. 项目app01
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class UserProfile(AbstractUser):
"""
用户
"""
name = models.CharField(max_length=30, null=True, blank=True, verbose_name="姓名")
birthday = models.DateField(null=True, blank=True, verbose_name="出生年月")
gender = models.CharField(max_length=6, choices=(("male", u"男"), ("female", "女")), default="female",
verbose_name="性别")
mobile = models.CharField(null=True, blank=True, max_length=11, verbose_name="电话")
email = models.EmailField(max_length=100, null=True, blank=True, verbose_name="邮箱")
class Meta:
verbose_name = "用户"
verbose_name_plural = verbose_name
def __str__(self):
return self.username
serializers.py 序列化文件
# -*- coding: utf-8 -*-
__author__ = 'hyh'
from django.contrib.auth import get_user_model
from rest_framework import serializers
User = get_user_model()
class UserRegSerializer(serializers.ModelSerializer):
# code = serializers.CharField(required=True, write_only=True, max_length=4, min_length=4,label="验证码",
# error_messages={
# "blank": "请输入验证码",
# "required": "请输入验证码",
# "max_length": "验证码格式错误",
# "min_length": "验证码格式错误"
# },
# help_text="验证码")
username = serializers.CharField(label="用户名", help_text="用户名", required=True, allow_blank=False,
validators=[UniqueValidator(queryset=User.objects.all(), message="用户已经存在")])
password = serializers.CharField(
style={'input_type': 'password'},help_text="密码", label="密码", write_only=True,
)
def create(self, validated_data):
user = super(UserRegSerializer, self).create(validated_data=validated_data)
user.set_password(validated_data["password"])
user.save()
return user
# def validate_code(self, code):
# # try:
# # verify_records = VerifyCode.objects.get(mobile=self.initial_data["username"], code=code)
# # except VerifyCode.DoesNotExist as e:
# # pass
# # except VerifyCode.MultipleObjectsReturned as e:
# # pass
# verify_records = VerifyCode.objects.filter(mobile=self.initial_data["username"]).order_by("-add_time")
# if verify_records:
# last_record = verify_records[0]
#
# five_mintes_ago = datetime.now() - timedelta(hours=0, minutes=5, seconds=0)
# if five_mintes_ago > last_record.add_time:
# raise serializers.ValidationError("验证码过期")
#
# if last_record.code != code:
# raise serializers.ValidationError("验证码错误")
#
# else:
# raise serializers.ValidationError("验证码错误")
def validate(self, attrs):
attrs["mobile"] = attrs["username"]
#del attrs["code"]
return attrs
class Meta:
model = User
fields = "__all__"
2.安装djangorestframework-jwt
pip install djangorestframework-jwt
配置settings文件
添加如下配置
import datetime
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
#'rest_framework_jwt.authentication.JSONWebTokenAuthentication', # 全局设置
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
),
}
JWT_AUTH = {
'JWT_EXPIRATION_DELTA': datetime.timedelta(days=7),
'JWT_AUTH_HEADER_PREFIX': 'JWT',
}
AUTH_USER_MODEL = 'app01.UserProfile' # 自定义用户表
#AUTHENTICATION_BACKENDS = (
# # 将backends添加进setting
# 'app01.views.CustomBackend',
#) 自定义认证不可用
# redis缓存
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"PASSWORD": "123456",
}
}
}
view.py
from django.shortcuts import render
from django.contrib.auth.backends import ModelBackend
from rest_framework import viewsets
from rest_framework import mixins
from rest_framework import authentication
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework_jwt.serializers import jwt_encode_handler, jwt_payload_handler
from django.contrib.auth import get_user_model
from .serializers import UserRegSerializer
from django.db.models import Q
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import UserProfile
from django.http import JsonResponse
from rest_framework.permissions import IsAuthenticated
from rest_framework import permissions
from app01.utils.permissions import IsOwnerOrReadOnly
from rest_framework_extensions.cache.mixins import CacheResponseMixin #pip3 install drf-extensions # 使用缓存ListCacheResponseMixin,RetrieveCacheResponseMixin
# Create your views here.
User = get_user_model()
#class CustomBackend(ModelBackend):
# """
# 自定义用户验证
# """
# def authenticate(self, username=None, password=None, **kwargs):
# try:
# user = UserProfile.objects.get(Q(username=username)|Q(mobile=username))
# if user.check_password(password):
# return user
# except Exception as e:
# return None
class UserViewset(CacheResponseMixin,mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.RetrieveModelMixin,mixins.ListModelMixin, viewsets.GenericViewSet):
serializer_class = UserRegSerializer
queryset = UserProfile.objects.all()
#permission_classes = (IsAuthenticated, IsOwnerOrReadOnly) # 权限和认证必须同时使用,否则认证不生效
authentication_classes = (JSONWebTokenAuthentication,authentication.SessionAuthentication)
def get_serializer_class(self):
if self.action == "retrieve":
return UserRegSerializer
elif self.action == "create":
return UserRegSerializer
return UserProfileSerializer
# permission_classes = (permissions.IsAuthenticated, )
def get_permissions(self):
if self.action == "retrieve":
return [permissions.IsAuthenticated()]
elif self.action == "list":
return [permissions.IsAuthenticated()] #list也需要认证
elif self.action == "create":
return []
return []
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = self.perform_create(serializer)
re_dict = serializer.data
payload = jwt_payload_handler(user)
re_dict["token"] = jwt_encode_handler(payload)
re_dict["name"] = user.name if user.name else user.username
headers = self.get_success_headers(serializer.data)
return Response(re_dict, status=status.HTTP_201_CREATED, headers=headers)
def get_object(self):
return self.request.user
def perform_create(self, serializer):
return serializer.save()
class Index(CacheResponseMixin,APIView):
permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
authentication_classes = (JSONWebTokenAuthentication,)
def get(self,request):
return JsonResponse({"index":"ok"})
3.urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import url,include
from rest_framework.routers import SimpleRouter,DefaultRouter
from rest_framework.documentation import include_docs_urls
from app01.views import UserViewset,Index
from rest_framework_jwt.views import obtain_jwt_token
router = SimpleRouter()
router.register('user',UserViewset,base_name='useruinfo')
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'docs/', include_docs_urls(title="user信息")),
url(r'^login/',obtain_jwt_token),
url(r'^index/',Index.as_view()),
]
urlpatterns += router.urls
4. 在app01下创建utils目录,存放permissions.py文件
permissions.py文件内容
# -*- coding: utf-8 -*-
__author__ = 'hyh'
from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
"""
Object-level permission to only allow owners of an object to edit it.
Assumes the model instance has an `owner` attribute.
"""
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
# Instance must have an attribute named `owner`.
return obj.user == request.user
4.测试
获取token
复制token
返回结果成功
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。