Rest Framework-视图组件-认证组件

一、视图组件

1、基本视图

models部分:

from django.db import models

# Create your models here.


class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()
    publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)
    authors=models.ManyToManyField(to='Author')
    def __str__(self):
        return self.name


    def test(self):
        return str(self.price)+self.name


class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDatail',to_field='nid',unique=True,on_delete=models.CASCADE)


class AuthorDatail(models.Model):
    nid = models.AutoField(primary_key=True)
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)


class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

    def __str__(self):
        return self.name

class User(models.Model):
    name=models.CharField(max_length=32)
    pwd=models.CharField(max_length=32)

class UserToken(models.Model):
    token = models.CharField(max_length=64)
    user=models.OneToOneField(to='User')

views部分:

===================================MySerializer.py===============================
from rest_framework import serializers
from app01 import models
from rest_framework.exceptions import ValidationErro

class PublishSerializer(serializers.ModelSerializer):
    class Meta:
        model=models.Publish
        fields='__all__'
        # fields=['id']
        # exclude=[]
        # depth=1
   
    book_names=serializers.SerializerMethodField()
    def get_book_names(self,obj):
        # 通过出版社对象,取出所有图书对象
        books=obj.book_set.all()
        book_ll=[book.name for book in books]
        return book_ll
   
    #局部,全局校验
    def validate_name(self,value):
        pass
        #写一堆判断逻辑
        #如果成功return valeu
        #如果失败,ValidationError

    def validate(self, attrs):
        pass
        #写一堆判断逻辑
        #如果成功return valeu
        #如果失败,ValidationError
        
===================================views.py===============================
from django.shortcuts import HttpResponse
from app01.MySerializer import PublishSerializer

def test(request):
    books=models.Book.objects.all()
    book_ser=PublishSerializer(instance=books,many=True)
    print(book_ser.data)

    #新增
    pub_ser=PublishSerializer(data=request.POST)
    if pub_ser.is_valid():
        pub_ser.save()
        
    #修改
    pub_ser = PublishSerializer(instance='要修改的对象',data=request.POST)
    if pub_ser.is_valid():
        pub_ser.save()
    else:
        pass
        #错误都在这里面
        #pub_ser.errors
    return HttpResponse('ok')
2、mixin类和generice类编写视图
===================================MySerializer.py===============================
from rest_framework import serializers
from app01 import models
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        #指定要序列化book这个表
        model=models.Book
        # 指定要序列化的字段
        # fields=['nid','name']
        #序列化所有字段
        fields='__all__'
===================================views.py===============================
from app01.MySerializer import BookSerializer
from app01.MySerializer import PublishSerializer
from rest_framework.mixins import CreateModelMixin, ListModelMixin, DestroyModelMixin, RetrieveModelMixin, \
    UpdateModelMixin
from rest_framework.generics import GenericAPIView

class BooksView(CreateModelMixin, ListModelMixin, GenericAPIView):
    serializer_class = BookSerializer
    queryset = models.Book.objects.all()

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)


class BookView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView):
    serializer_class = BookSerializer
    queryset = models.Book.objects.all()

    def get(self, request, *args, **kwargs):
        # 获取单条
        return self.retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return self.update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)


class PublishView(CreateModelMixin, GenericAPIView):
    serializer_class = PublishSerializer

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
3、使用generics 下ListCreateAPIView,RetrieveUpdateDestroyAPIView
from rest_framework.generics import ListAPIView,ListCreateAPIView,RetrieveUpdateDestroyAPIView,DestroyAPIView,CreateAPIView
# 它有两个接口,一个是获取所有,一个是新增
class BooksView(ListCreateAPIView):
    serializer_class=BookSerializer
    queryset=models.Book.objects.all()

class BookView(RetrieveUpdateDestroyAPIView):
    serializer_class=BookSerializer
    queryset=models.Book.objects.all()
4、使用ModelViewSet

视图层:

# 5种请求:get,get,post,put,delete
rom rest_framework.viewsets import ModelViewSet
class BooksView(ModelViewSet):
    queryset=models.Book.objects.all()
    serializer_class=BookSerializer

路由层:

#继承ModelViewSet之后的视图类,路由写法
url(r'^books/$', views.BooksView.as_view({'get':'list','post':'create'})),
url(r'^books/(?P<pk>\d+)', views.BooksView.as_view({'get':'retrieve','put':'update','delete':'destroy'})),
5、ViewSetMixin的使用

视图层:

# 最终一般用的时候,会经常用ViewSetMixin
# ViewSetMixin干了什么事?重写了as_view方法
from rest_framework.viewsets import ViewSetMixin
class Publish(ViewSetMixin,APIView):
    def aa(self,request):
        return HttpResponse('aa')
    def bb(self,request):
        return HttpResponse('bb')
    def get_all(self,request):
        pass
    def get_one(self,request):
        pass
    def create(self,request):
        pass
    def create_by_id(self,request):
        pass

视图层:

url(r'^test', views.Publish.as_view({'get':'aa'})),
url(r'^xx', views.Publish.as_view({'post':'bb'})),

二、认证组件

1、认证简介
只有认证通过的用户才能访问指定的url地址 比如:查询课程信息需要登录之后才能查看,没有登录,就不能查看,这时候需要用到认证组件
2、认证的使用

视图层:

from app01 import models
# 认证组件
from rest_framework.views import APIView
from rest_framework.request import Request
from rest_framework.exceptions import AuthenticationFailed
import uuid
'''
使用认证功能
写一个类MyAuthetication
写两个方法,一个是authenticate,一个是authenticate_header
在authenticate方法中写认证逻辑,认证通过返回空,认证不通过抛异常
'''
class MyAuthetication():
    def authenticate(self,request):
        # 认证相关的东西,校验该次请求是否携带正确的token
        # 取出token
        token=request.GET.get('token')
        # 去数据库中查看token
        ret=models.UserToken.objects.filter(token=token).first()
        if ret:
            # 正常通过认证的用户
            return None
        else:
            # 没有登录或者非法用户
            raise AuthenticationFailed('您没有通过认证')
    def authenticate_header(self,xx):
        pass
    
class BooksView(APIView):
    # 比如某个视图类需要登陆后才能查看,只需要在视图类加入
    authentication_classes=[MyAuthetication]
    def get(self,request):
        return Response('ok')
    
    
#写登录接口
class Login(APIView):
    def post(self,request):
        response={'status':100,'msg':None}
        name=request.data.get('name')
        pwd=request.data.get('pwd')
        #去数据库校验该用户是否存在
        user=models.User.objects.filter(name=name,pwd=pwd).first()
        if user:
            # 正常用户登录成功,返回一个唯一的随机字符串
            token=uuid.uuid4()
            #把生成的随机字符串存到数据库中
            # 这样不行,因为每次登录都会新插入一条
            # models.UserToken.objects.create(user=user,token=token)
            # 先去数据库中查询,如果当前用户存在记录,更新token,如果不存在,新增一条
            # 根据user取查询,如果查到数据更新defaults中的数据,如果查不到,新增一条数据
            ret=models.UserToken.objects.update_or_create(user=user,defaults={'token':token})
            response['msg']='登录成功'
            response['token']=token
        else:
            #用户名或密码错误
            response['status'] = 101
            response['msg'] = '用户名或密码错误'
        return Response(response)

路由层:

url(r'^books/', views.BooksView.as_view()),
url(r'^login/', views.Login.as_view()),
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值