系统的接口编写
1.创建serializers.py文件
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.HyperLinkedModelSerializer):
class Meta:
model = Book
fields = ("url", "book_name", "book_price")
# 也可以继承 serializers.ModelSerializer 将展示的url换成id
class BookSerializer1(serializers.ModelSerializer):
class Meta:
model = Book
fields = ("id", "book_name", "book_price")
2.在views.py中写视图函数
#FBV、CBV
#FBV:使用函数处理请求 函数视图
#CBV:使用类处理请求 类视图
from rest_framework import viewset
class BookView(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
3.在urls.py中加载路由
from rest_framework import routers
router = routers.DefaultRouter()
router.register(r'books', views.BookView()
4.最后在主url文件中导入
from urls import router
urlpatterns = [
path('api/', include(router.urls))
]
这样就完成了一个最简单的接口注册
三种展示数据的形式
HyperLinkedModelSerializer继承于ModelSerializer继承于Serializer
1.直接是超链接
class BookSerializer(serializers.HyperLinkedModelSerializer):
class Meta:
model = Book
fields = ("url", "book_name", "book_price")
测试返回的结果如下:
{
"url": http://xxxxx/api/books/1/, # 可以直接点进去查看详情
"book_name": "西游记",
"book_price": 100.1
},
- 使用模型中自带的字段在返回页面展示
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ("id", "book_name", "book_price")
测试返回的结果如下:
{
"id": 1,
"book_name": "西游记",
"book_price": 100.1
},
3.继承最底层的Serializer方法
class BookSerializer(serializers.Serializer):
id = serializer.IntegerField(read_onle=True)
book_name = serializer.CharField()
book_price = serializer.FloatField()
# instance 更新的信息
# validated_data 获取信息
def update(self, instance, validated_data):
instance.book_name = validated_data.get("book_name") or instance.book_name
instance.book_price = validated_data.get("book_price") or instance.book_price
instance.save()
return instance
def create(self, validated_data):
return Book.objects.create(**validated_data)
类视图的限制
1.CreateAPIView:只接收post请求
#这里只想创建一个Game
class GameCreateApiView(CreateAPIView): # 只接受post请求 类视图的方式
queryset = Game.objects.all()
serializer_class = GameSerializer
2.ListAPIView:只接收get请求
class GameCreateApiView(ListAPIView): #只接受get请求
queryset = Game.objects.all()
serializer_class = GameSerializer # 序列化到serializer映射出去
3.ListCreateAPIView:接收post get 请求
class GameCreateApiView(ListCreateAPIView): # 接受post 和 get 请求
queryset = Game.objects.all()
serializer_class = GameSerializer
用户的登陆注册以及携带Token
class UserCreateApiView(CreateAPIView):
serializer_class = UserSerializer
def post(self, request, *args, **kwargs):
action = request.query_params.get("action") # 获取的url中的参数是:register
# action = request.POST.get("action") 获取的是:None
if action == 'register':
return self.create(request, *args, **kwargs)
elif action == "login":
return self.do_login(request, *args, **kwargs)
else:
raise APIException("请提供正确的请求")
return HttpResponse('666')
def do_login(self, request, *args, **kwargs):
user_name = request.POST.get("user_name")
user_password = request.POST.get("user_password")
try:
user = User.objects.filter(user_name=user_name).first()
except User.DoesNotExist as e:
print(e)
raise NotFound(detail="用户不存在")
if user.user_password != user_password:
raise APIException(detail="用户密码错误")
token = uuid.uuid4().hex
cache.set(token, user.id, timeout=60*60*7*24)
data = {
"status": status.HTTP_200_OK,
"msg": "登陆成功",
"token": token
}
return Response(data)
settings.py中设置redis(要确保安装了diango_redis)
from django_redis.client import DefaultClient
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"PASSWORD": "xxx" # redis的密码,没有可以不写
}
}
}
只有登陆的用户才有查看电影的权限
1.在MovieView.py中写入
class MovieView(viewsets.ModelViewSet):
queryset = Movie.objects.all()
serializer_class = MovieSerializer
authentication_classes = UserAuthentication,
permission_classes = UserLoginPermission,
authentications.py
class UserAuthentication(BaseAuthentication):
def authenticate(self, request):
try:
token = request.query_params.get("token")
user_id = cache.get(token)
user = User.objects.get(pk=user_id)
return user, token
except Exeption as e:
print(e)
return None
permissions.py
class UserLoginPermission(BasePermission):
def has_permission(self, request, view):
return isinstance(request.user, User)