1.官网
https://www.django-rest-framework.org/tutorial/quickstart/#quickstart
2.目录结构

models.py
from django.db import models # Create your models here. from django.db import models # Create your models here. class User(models.Model): name=models.CharField(max_length=32) pwd=models.CharField(max_length=32) type_choices=((1,"普通用户"),(2,"VIP"),(3,"SVIP")) user_type=models.IntegerField(choices=type_choices,default=1) class Token(models.Model): user=models.OneToOneField("User") token = models.CharField(max_length=128) def __str__(self): return self.token class Book(models.Model): title=models.CharField(max_length=32) price=models.IntegerField() pub_date=models.DateField() publish=models.ForeignKey("Publish") authors=models.ManyToManyField("Author") def __str__(self): return self.title class Publish(models.Model): name=models.CharField(max_length=32) email=models.EmailField() def __str__(self): return self.name class Author(models.Model): name=models.CharField(max_length=32) age=models.IntegerField() def __str__(self): return self.name
serilizer.py
# by luffycity.com from rest_framework import serializers from app01.models import * # 为queryset,model对象做序列化 class PublishSerializers(serializers.Serializer): name = serializers.CharField() email = serializers.CharField() class PublishModelSerializers(serializers.ModelSerializer): class Meta: model=Publish fields="__all__" # class BookSerializers(serializers.Serializer): # title = serializers.CharField(max_length=32) # price = serializers.IntegerField() # pub_date = serializers.DateField() # publish=serializers.CharField(source="publish.name") # #authors=serializers.CharField(source="authors.all") # authors = serializers.SerializerMethodField() # def get_authors(self,obj): # temp=[] # for obj in obj.authors.all(): # temp.append(obj.name) # return temp ''' 序列化BookSerializers(book_list,many=True)过程: temp=[] for obj in book_list: temp.append({ "title":obj.title, "price":obj.price, "pub_date":obj.pub_date, "publish":str(obj.publish), # obj.publish.name #"authors":obj.authors.all, "authors": get_authors(obj) }) ''' class BookModelSerializers(serializers.ModelSerializer): class Meta: model = Book fields = "__all__" #publish=serializers.CharField(source="publish.pk") publish=serializers.HyperlinkedIdentityField( view_name="detailpublish", lookup_field="publish_id", lookup_url_kwarg="pk", ) # authors=serializers.CharField(source="authors.all") # authors = serializers.SerializerMethodField() # def get_authors(self,obj): # temp=[] # for obj in obj.authors.all(): # temp.append(obj.name) # return temp def create(self, validated_data): print("validated_data",validated_data) book=Book.objects.create(title=validated_data["title"],price=validated_data["price"],pub_date=validated_data["pub_date"],publish_id=validated_data["publish"]["pk"]) book.authors.add(*validated_data["authors"]) return book class AuthorModelSerializers(serializers.ModelSerializer): class Meta: model = Author fields = "__all__"
utils.py
from rest_framework import exceptions from rest_framework.authentication import BaseAuthentication from .models import * class TokenAuth(BaseAuthentication): def authenticate(self,request): token = request.GET.get("token") token_obj = Token.objects.filter(token=token).first() if not token_obj: raise exceptions.AuthenticationFailed("验证失败!") else: return token_obj.user.name,token_obj.token class SVIPPermission(object): message="只有超级用户才能访问" def has_permission(self,request,view): username=request.user user_type=User.objects.filter(name=username).first().user_type if user_type==3: return True # 通过权限认证 else: return False
views.py
from django.shortcuts import render,HttpResponse # Create your views here. from django.views import View from rest_framework.response import Response from .models import * from app01.serilizer import * from rest_framework.views import APIView # Publish表 class PublishView(APIView): def get(self,request): # restframework # 取数据 # print("request.data", request.data) # print("request.data type", type(request.data)) # print(request._request.GET) # print(request.GET) # 序列化 # 方式1: # publish_list=list(Publish.objects.all().values("name","email")) # 方式2: # from django.forms.models import model_to_dict # publish_list=Publish.objects.all() # temp=[] # for obj in publish_list: # temp.append(model_to_dict(obj)) # 方式3: # from django.core import serializers # ret=serializers.serialize("json",publish_list) # 序列组件 publish_list = Publish.objects.all() ps = PublishModelSerializers(publish_list, many=True) return Response(ps.data) def post(self,request): # 取数据 # 原生request支持的操作 # print("POST",request.POST) # print("body",request.body) # # print(request) # print(type(request)) # from django.core.handlers.wsgi import WSGIRequest # 新的request支持的操作 # print("request.data",request.data) # print("request.data type",type(request.data)) # # post请求的数据 ps = PublishModelSerializers(data=request.data) if ps.is_valid(): print(ps.validated_data) ps.save() # create方法 return Response(ps.data) else: return Response(ps.errors) class PublishDetailView(APIView): def get(self, request, pk): publish = Publish.objects.filter(pk=pk).first() ps = PublishModelSerializers(publish) return Response(ps.data) def put(self, request, pk): publish = Publish.objects.filter(pk=pk).first() ps = PublishModelSerializers(publish, data=request.data) if ps.is_valid(): ps.save() return Response(ps.data) else: return Response(ps.errors) def delete(self, request, pk): Publish.objects.filter(pk=pk).delete() return Response() from rest_framework.parsers import JSONParser,FormParser,MultiPartParser,FileUploadParser # Book表 from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination class MyPageNumberPagination(PageNumberPagination): page_size = 1 page_query_param = 'page' page_size_query_param="size" max_page_size=2 class MyLimitOffsetPagination(LimitOffsetPagination): default_limit=1 class BookView(APIView): # authentication_classes = [TokenAuth,] # [TokenAuth(),] # permission_classes = [] # throttle_classes = [] parser_classes = [JSONParser,FormParser] def get(self,request): print("request.user",request.user) print("request.auth",request.auth) print("_request.body",request._request.body) print("_request.GET",request._request.GET) book_list=Book.objects.all() # 分页 pnp=MyLimitOffsetPagination() books_page=pnp.paginate_queryset(book_list,request,self) bs=BookModelSerializers(books_page,many=True,context={'request': request}) return Response(bs.data) def post(self,request): # post请求的数据 print("request.data",request.data) bs=BookModelSerializers(data=request.data) if bs.is_valid(): print(bs.validated_data) bs.save()# create方法 return Response(bs.data) else: return Response(bs.errors) class BookDetailView(APIView): def get(self,request,id): book=Book.objects.filter(pk=id).first() bs=BookModelSerializers(book,context={'request': request}) return Response(bs.data) def put(self,request,id): book=Book.objects.filter(pk=id).first() bs=BookModelSerializers(book,data=request.data) if bs.is_valid(): bs.save() return Response(bs.data) else: return Response(bs.errors) def delete(self,request,id): Book.objects.filter(pk=id).delete() return Response() # ##############################################################Author # from rest_framework import mixins # from rest_framework import generics # # class AuthorView(mixins.ListModelMixin,mixins.CreateModelMixin,generics.GenericAPIView): # queryset=Author.objects.all() # serializer_class =AuthorModelSerializers # # def get(self,request, *args, **kwargs): # return self.list(request, *args, **kwargs) # def post(self,request, *args, **kwargs): # return self.create(request, *args, **kwargs) # # # class AuthorDetailView(mixins.RetrieveModelMixin,mixins.DestroyModelMixin,mixins.UpdateModelMixin,generics.GenericAPIView): # queryset = Author.objects.all() # serializer_class = AuthorModelSerializers # # def get(self,request,*args, **kwargs): # return self.retrieve(request,*args, **kwargs) # # def delete(self,request,*args, **kwargs): # return self.destroy(request,*args, **kwargs) # # def put(self,request,*args, **kwargs): # return self.retrieve(request,*args, **kwargs) ############################################################################## # # from rest_framework import mixins # from rest_framework import generics # # # class AuthorView(generics.ListCreateAPIView): # queryset=Author.objects.all() # serializer_class =AuthorModelSerializers # # class AuthorDetailView(generics.RetrieveUpdateDestroyAPIView): # queryset = Author.objects.all() # serializer_class = AuthorModelSerializers ############################################################################## from rest_framework import viewsets from app01.utils import TokenAuth from app01.utils import SVIPPermission class VisitRateThrottle(object): def allow_request(self,request,view): # 要求访问站点的频率不能超过每分钟20次 if 1: print(request.META.get("REMOTE_ADDR")) return True else: return False from rest_framework.response import Response class AuthorModelView(viewsets.ModelViewSet): #authentication_classes = [TokenAuth,] #permission_classes=[SVIPPermission,] #throttle_classes = [VisitRateThrottle] # 限制某个IP每分钟访问次数不能超过20次 queryset = Author.objects.all() serializer_class = AuthorModelSerializers pagination_class = MyPageNumberPagination renderer_classes = [] def get_random_str(user): import hashlib,time ctime=str(time.time()) md5=hashlib.md5(bytes(user,encoding="utf8")) md5.update(bytes(ctime,encoding="utf8")) return md5.hexdigest() from .models import User class LoginView(APIView): authentication_classes = [] def post(self,request): name=request.data.get("name") pwd=request.data.get("pwd") user=User.objects.filter(name=name,pwd=pwd).first() res = {"state_code": 1000, "msg": None} if user: random_str=get_random_str(user.name) token=Token.objects.update_or_create(user=user,defaults={"token":random_str}) res["token"]=random_str else: res["state_code"]=1001 #错误状态码 res["msg"] = "用户名或者密码错误" import json return Response(json.dumps(res,ensure_ascii=False))
settings.py
""" Django settings for restdemo project. Generated by 'django-admin startproject' using Django 1.11.1. For more information on this file, see https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.11/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'zh7zb+r@$sgy(e=2p%dh7229g2z*diug%7ifpg$53a8=_gvi=d' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', "rest_framework", ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', #'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'restdemo.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates'),], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'restdemo.wsgi.application' # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } # Password validation # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/' REST_FRAMEWORK = { # "DEFAULT_AUTHENTICATION_CLASSES": ["app01.utils.TokenAuth",], # "DEFAULT_PERMISSION_CLASSES": ["app01.utils.SVIPPermission",], # "PAGE_SIZE":1 }
urls.py
"""restdemo URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url,include from django.contrib import admin from rest_framework import routers from app01 import views routers=routers.DefaultRouter() routers.register("authors",views.AuthorModelView) urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^publishes/$', views.PublishView.as_view(),name="publish"), # View:view(request)=====APIView:dispatch() url(r'^publishes/(?P<pk>\d+)/$', views.PublishDetailView.as_view(),name="detailpublish"), # View:view(request)=====APIView:dispatch() url(r'^books/$', views.BookView.as_view(),name="books"), url(r'^books/(\d+)/$', views.BookDetailView.as_view(),name="detailbook"), #url(r'^books/(\d+)/$', View:view), # view(request) # url(r'^authors/$', views.AuthorModelView.as_view({"get":"list","post":"create"}),name="author"), # url(r'^authors/(?P<pk>\d+)/$', views.AuthorModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}),name="detailauthor"), # url(r'', include(routers.urls)), url(r'^login/$', views.LoginView.as_view(),name="login"), ]
浙公网安备 33010602011771号