DRF 3小时
源码:苏德琪/Django - 码云 - 开源中国 (gitee.com)
1.运行项目:
在终端内,python manage.py runserver 0.0.0.0:8000,运行manage.py文件
(1)在浏览器内打到端口查询
- [Course List – Django REST framework]http://127.0.0.1:8000/course/fbv/list/
- [DRF API文档] http://127.0.0.1:8000/docs/
(2)在postman中测试端口
删除节信息:delete
2.新建项目
(1)新建Django工程
(2)基本信息配置
setting中更改信息:
#修改
ALLOWED_HOSTS = ["*"]
……
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False
……
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': []
,
'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',
],
},
},
]
……
#末尾添加
STATIC_ROOT = os.pardir.join(BASE_DIR, 'static')
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'staticfiles')
]
终端内执行命令:
python manage.py makemigrations
python manage.py migrate

在 Django 中,当你的模型发生变化时(例如添加、删除或修改模型的字段),你需要创建一个数据库迁移文件,以便将这些变化应用到数据库中。迁移文件记录了对数据库的修改操作,包括创建、修改或删除表、列、索引等。
- 运行
python manage.py makemigrations
命令会分析你的模型文件,并生成包含数据库迁移操作的文件。这些文件将被存储在应用程序的migrations
文件夹中。 - 生成迁移文件后,你可以使用
python manage.py migrate
命令来应用这些迁移,将数据库结构与模型保持同步。
总结起来,python manage.py makemigrations
命令是用于生成数据库迁移文件,以记录模型的变化,而 python manage.py migrate
命令是用于应用这些迁移文件,更新数据库结构。
配置用户信息
python manage.py createsuperuser

这里我的用户名:
- dq
- dq271828
运行查看:[站点管理 | Django 站点管理员]http://127.0.0.1:8000/admin/
setting中配置drf:
INSTALLED_APPS = [
……
'rest_framework', # RESTful API
'rest_framework.authtoken', # DRF自带的token认证
]
……
# drf全局配置,最后添加
rest_framework = {
'DEFAULT_PERMISSION_CLASSES': ['rest_framework.pagination.PageNUmberPagination'],
'page_size': 50,
'datetime_format': '%Y-%m-%d %H:%M:%S',
'default_renderer_classes': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
'default_parser_classes': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
'rest_framework.parsers.MultiPartParser',
],
'default_permission_classes': [
'rest_framework.permissions.isAuthenticated',
],
'default_authentication_classes': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.TokenAuthentication',
]
}
终端内执行命令:
python manage.py makemigrations
python manage.py migrate

urls中配置信息:
from django.contrib import admin
from django.urls import path, include # include()函数用于包含其它URLconf
urlpatterns = [
path('api-auth/', include('rest_framework.urls')),
path('admin/', admin.site.urls),
]
运行工程drf:

网页端打到网址:http://127.0.0.1:8000/api-auth/login/
成功跳转到这个路由:accounts/profile/
3.序列化
(1)course app搭建(课程信息模型类)
- course\apps.py
from django.apps import AppConfig
class CourseConfig(AppConfig):
name = 'course'
verbose_name = '课程信息'
- course\models.py
from django.db import models
from django.conf import settings
class Course(models.Model):
name = models.CharField(max_length=255, unique=True, help_text='课程名称', verbose_name='名称')
introduction = models.TextField(help_text='课程简介', verbose_name='简介')
teacher = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, help_text='任课老师',
verbose_name='讲师')
price = models.DecimalField(max_digits=6, decimal_places=2, help_text='课程价格', verbose_name='价格')
create_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
update_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
class Meta:
db_table = 'course'
verbose_name = '课程信息'
verbose_name_plural = verbose_name
ordering = ('price',)
def __str__(self):
return self.name
- course\admin.py
from django.contrib import admin
from .models import Course
@admin.register(Course)
class CourseAdmin(admin.ModelAdmin):
list_display = ('name', 'introduction', 'teacher', 'price')
serch_fields = list_display
list_filter = list_display
终端内执行命令:
python manage.py makemigrations
python manage.py migrate
项目中已经生成migrations文件夹
添加课程信息:
在控制台中序列化课程信息:(Django自带序列化工具)
from course.models import Course
from django.core import serizlizaers
serializers.serialize('json',Course.objects.all()) #序列化全部字段
serializers.serialize('json',Course.objects.all(),fields=("name")) #序列化 name 字段
(2)序列化模型类
在app下面建立一个序列化文件
- serializers.py中:
from django import forms
from rest_framework import serializers
from .models import Course
from django.contrib.auth.models import User
# form类
class CourseForm(forms.ModelForm):
class Meta:
model = Course
fields = ('name', 'introduction', 'teacher', 'price')
# 模型类
class CourseSerializer(serializers.ModelSerializer):
teacher = serializers.ReadOnlyField(source='teacher.username') # 只读字段
class Meta:
model = Course
fields = '__all__'
# 用户类
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__' # 所有字段
(3)带URL的HyperlinkedModelSerializer
- serializers.py中:
class CourseSerializer(serializers.HyperlinkedModelSerializer):
teacher = serializers.ReadOnlyField(source='teacher.username') # 只读字段
class Meta:
model = Course
fields = ('id', 'url', 'name', 'introduction', 'teacher', 'price', 'create_at', 'update_at')
4.DRF视图开发RESTful APl接口
- 函数式编程Function Based View
- 类视图Classed Based View
- 通用类视图Generic Classed Based View
- DRF的视图集viewsets
(1)Django原生view开发Api接口
views.py中:
import json
from django.http import JsonResponse, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.views import View
from django.utils.decorators import method_decorator
course_dict = {
'name': '课程名称',
'introduction': '课程介绍',
'price': 100,
}
# Django FBV 编写API接口
@csrf_exempt
def course_list(request):
if request.method == 'GET':
return HttpResponse(json.dumps(course_dict), content_type='application/json')
# return JsonResponse(course_dict)
if request.method == 'POST':
course = json.loads(request.body.decode('utf-8')) # json.loads()将json字符串转换为python字典
# return HttpResponse(json.dumps(course), content_type='application/json')
return JsonResponse(course, safe=False) # safe=False表示可以传递非字典类型的数据
# Django CBV 编写API接口
@method_decorator(csrf_exempt, name='dispatch')
class CourseList(View):
def get(self, request):
return JsonResponse(course_dict)
def post(self, request):
course = json.loads(request.body.decode('utf-8'))
return HttpResponse(json.dumps(course), content_type='application/json')
(2)函数式编程
获取所有课程信息或新增一个课程
- course/views中:
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .models import Course
from .serializers import CourseSerializer
# 一、 函数式编程 Function Based View
@api_view(["GET", "POST"])
def course_list(request):
"""
获取所有课程信息或新增一个课程
:param request:
:return:
"""
if request.method == "GET":
s = CourseSerializer(instance=Course.objects.all(), many=True)
return Response(data=s.data, status=status.HTTP_200_OK) # 序列化
elif request.method == "POST":
s = CourseSerializer(data=request.data) # 反序列化
if s.is_valid():
s.save(teacher=request.user)
return Response(data=s.data, status=status.HTTP_201_CREATED)
return Response(s.errors, status=status.HTTP_400_BAD_REQUEST)
- course/serializers.py中:
# 模型类
class CourseSerializer(serializers.ModelSerializer):
teacher = serializers.ReadOnlyField(source='teacher.username') # 只读字段
class Meta:
model = Course
fields = '__all__'
- course/urls中:(新建文件)
from django.urls import path, include
from course import views
urlpatterns = [
path("fbv/list/", views.course_list, name="fbv_list")
]
- drf/urls中:
from django.contrib import admin
from django.urls import path, include # include()函数用于包含其它URLconf
urlpatterns = [
path('api-auth/', include('rest_framework.urls')),
path('admin/', admin.site.urls),
path('course/', include('course.urls'))
]

- 测试post:(反序列化)
{
"name": "Django 快速入",
"introduction": "测",
"price": "0.99"
}
获取、更新、删除一个课程
- course/views中继续写:
@api_view(["GET", "PUT", "DELETE"])
def course_detail(request, pk): # 获取、更新、删除一个课程
try:
course = Course.objects.get(pk=pk)
except Course.DoesNotExist:
return Response(data={"msg": "没有此课程信息"}, status=status.HTTP_404_NOT_FOUND)
else:
if request.method == "GET":
s = CourseSerializer(instance=course)
return Response(data=s.data, status=status.HTTP_200_OK)
elif request.method == "PUT":
s = CourseSerializer(instance=course, data=request.data)
if s.is_valid():
s.save() # 区别于增添课程信息
return Response(data=s.data, status=status.HTTP_200_OK)
return Response(data=s.errors, status=status.HTTP_400_BAD_REQUEST)
elif request.method == "DELETE":
course.delete()
return Response(data={"msg": "删除成功"}, status=status.HTTP_204_NO_CONTENT)
- course/urls中:
urlpatterns = [
path("fbv/list/", views.course_list, name="fbv_list"),
path("fbv/detail/<int:pk>/", views.course_detail, name="fbv_detail")
]
(3)使用Postman测试API接口
GET请求:
http://127.0.0.1:8000/course/fbv/list/
- 利用密码认证:
用户名:dq
密码:dq271828
- 利用token认证:
https://api.github.com/user/repos
Key:Authorization
Value:Token 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
POST请求:
密码授权——>Body/raw-JSON——>添加信息,发送请求
在网页端也能看到新增的第3条信息:
GET单个请求:
http://127.0.0.1:8000/course/fbv/detail/2/
PUT更新请求:
更改课程3的价格
DELETE请求:
(4)类视图编程
- course/views中:
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from rest_framework.views import APIView
from .models import Course
from .serializers import CourseSerializer
# 二、 类视图 Class Based View
class CourseList(APIView):
def get(self, request):
s = CourseSerializer(instance=Course.objects.all(), many=True) # 序列化,这里是instance
return Response(data=s.data, status=status.HTTP_200_OK)
def post(self, request):
s = CourseSerializer(data=request.data) # 反序列化,这里是data
if s.is_valid():
s.save(teacher=request.user)
print(type(request.data), type(s.data))
return Response(data=s.data, status=status.HTTP_201_CREATED)
return Response(s.errors, status=status.HTTP_400_BAD_REQUEST)
- course/urls中:(新建文件)
from django.urls import path
from course import views
urlpatterns = [
# Function-Based Views
path("fbv/list/", views.course_list, name="fbv_list"),
path("fbv/detail/<int:pk>/", views.course_detail, name="fbv_detail"),
# Class-Based Views
path("cbv/list/", views.CourseList.as_view(), name="cbv_list"),
]
-
利用postman测试端口
5.DRF认证方式
(1)使用Django manage.py手动生成Token
- 在settings——>INSTALLED_APPS中,添加'rest_framework.authtoken'
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework', # RESTful API
'rest_framework.authtoken', # DRF自带的token认证
'course.apps.CourseConfig',
]
- 在settings——>rest_framework中,添加'rest_framework.authentication.TokenAuthentication'
- 在终端输入命令:python manage.py drf_create_token dq
- db.sqlite3中也可以看到key值
(2)Django信号机制自动生成Token
a.信号机制自动生成Token
- 在views中导入:
from django.db.models.signals import post_save
from django.conf import settings
from django.dispatch import receiver
from rest_framework.authtoken.models import Token
@receiver(post_save, sender=settings.AUTH_USER_MODEL) # Django的信号机制
def generate_token(sender, instance=None, created=False, **kwargs):
"""
创建用户时自动生成Token
:param sender:
:param instance:
:param created:
:param kwargs:
:return:
"""
if created:
Token.objects.create(user=instance)
-
在drf——>views中添加:
from rest_framework.authtoken import views # DRF自带的token认证
path('api-token-auth/', views.obtain_auth_token), # 获取token的接口
from django.contrib import admin
from django.urls import path, include # include()函数用于包含其它URLconf
from rest_framework.authtoken import views # DRF自带的token认证
urlpatterns = [
path('api-token-auth/', views.obtain_auth_token), # 获取token的接口
path('api-auth/', include('rest_framework.urls')),
path('admin/', admin.site.urls),
path('course/', include('course.urls'))
]
b.测试新建用户是否生成
- 运行工程
- 新建用户: user01
- 返回看到:user01有效
- 在db.sqlite3——>authtoken中可以看到新增的token
c.利用postman测试api-token-auth接口:
- 利用postman添加新用户,生成token
- 利用token认证(API Key),查询列表
- 响应成功
6.DRF接口文档生成
- drf——>settings中,添加:
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'
}
- drf——>urls中,添加:
from rest_framework.documentation import include_docs_urls # DRF自带的文档
urlpatterns = [
path('docs/', include_docs_urls(title='DRF API文档', description='Django REST framework快速入门')),
]
- 运行工程,打到:http://127.0.0.1:8000/docs/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?