环境安装:
安装新版python
# 查看python版本
$ python -V
建议安装最新版,看网上有些方法装下来的python版本也不是最新的,可以去官网查看最新版安装链接,下载后解压,安装。
# 下载
$ wget https://www.python.org/ftp/python/3.8.3/Python-3.8.3.tgz
# 解压
$ tar zxvf Python-3.8.3.tgz
$ cd Python-3.8.3/
# 配置
$ ./configure
# pip是python的包管理软件,如果没有的话需安装
$ yum -y install python-pip
DRF默认用SQLite作为数据库,公司的centos服务器没有SQLite需要安装
# 安装SQLite
$ yum install sqlite-devel
(optional)为了使包配置独立于其他的项目,可以创建一个虚拟环境
$ python3 -m venv env
$ source env/bin/activate
要退出虚拟环境,在任意地方deactivate即可
$ deactivate
# 安装Django
$ pip install django
# 安装DRF
$ pip install djangorestframework
创建项目
# 创建项目
$ django-admin startproject 项目名
# 创建app
$ python manage.py startapp forum
然后需要在项目下settings.py中修改已安装的app
INSTALLED_APPS = [
...
'rest_framework',
'forum',
]
打🐎
创建模型
# models.py
class Article(models.Model):
title = models.CharField(max_length=100, default='')
content = models.TextField(default='')
created = models.DateTimeField(auto_now_add=True)
last_modify_date = models.DateTimeField(auto_now=True)
author = models.TextField()
dingId = models.TextField(default='lost')
avatar = models.TextField(default='0')
type = models.TextField(default='0')
likes = models.IntegerField(default=0)
comments = models.IntegerField(default=0)
reports = models.IntegerField(default=0)
selected = models.BooleanField(default=False)
deleted = models.BooleanField(default=False)
class Meta:
db_table = 'article'
模型迁移至数据库
$ python manage.py makemigrations snippets
$ python manage.py migrate
# 将会在SQLite建立名为article的表
序列化,将实例转化为json
# serializers.py
from rest_framework import serializers
from forum.models import Article
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = '__all__'
# fields = ('id', 'title', 'content', 'last_modify_date', 'created')
接口Views
# views.py
from rest_framework import viewsets
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
短短这几行就实现了增删改查,真是十分好用
Router
# urls.py
from rest_framework.routers import DefaultRouter
from forum import views
forumPrefix = 'api/forum/'
forumRouter = DefaultRouter()
forumRouter.register('article', views.ArticleViewSet)
forumRouter.register('comment', views.CommentViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
path(forumPrefix, include(forumRouter.urls)),
]
运行
一切准备就绪,此时cd到项目根目录,然后访问http://127.0.0.1:8000/api/forum/ 就可以看到新写的接口了,推荐用Postman测试
$ python manage.py runserver
Validating models...
0 errors found
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
如果需要在服务器上长期运行:
$ nohup python3 manage.py runserver 0.0.0.0:8000 > out.log 2>&1 &
# 查看输出
$ tail -f out.log
参数过滤
安装requests
$ pip install requests
安装django-url-filter
安装django-filter
$ pip install django-filter
$ pip install django-url-filter
# views
from url_filter.integrations.drf import DjangoFilterBackend
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
filter_backends = [DjangoFilterBackend]
filter_fields = ['selected', 'deleted', 'reports', 'type']
比如我想筛选用户A点赞数为5到10的文章,前端可以直接把筛选条件拼在url后,十分好用!
.../forum/articles/?author=A&likes__range=5,10
详细的使用说明在:https://django-url-filter.readthedocs.io/en/latest/
排序
# views
from rest_framework import filters
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
filter_backends = [filters.OrderingFilter, DjangoFilterBackend]
filter_fields = ['selected', 'deleted', 'reports', 'type']
ordering_fields = ('id', 'created', 'last_modify_date')
比如要按创建时间倒序排列
.../forum/articles/?ordering=-create
真好用!详细说明在:https://www.django-rest-framework.org/api-guide/filtering/
@action为viewsets添加更多功能
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
filter_backends = [filters.OrderingFilter, DjangoFilterBackend, filters.SearchFilter]
ordering_fields = ('id', 'created', 'last_modify_date')
filter_fields = ['selected', 'deleted', 'reports', 'type']
search_fields = ['id', 'title', 'content']
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
@action(detail=True, method=['GET'])
# detail=False时,对所有集合产生效果,method默认为GET可省略
def like(self, request, pk=None):
article = self.get_object()
article.likes += 1
article.save()
return Response(article.likes)
修改viewset的CURD方法
class UserViewSet(viewsets.ViewSet):
def list(self, request):
pass
def create(self, request):
pass
def retrieve(self, request, pk=None):
pass
def update(self, request, pk=None):
pass
def partial_update(self, request, pk=None):
pass
def destroy(self, request, pk=None):
pass
跨域
由于我之前没接触过后端开发,跨域可真是恶心死我了,看网上有说用corsheaders的,我试了不太好使,也有说自己写一个middleware的,然后按网上的说法我上线后新款iPhone跟模拟器都没问题,但剩下的90%的设备还是存在跨域问题,最终发现,Access-Control-Allow-Methods不能为*
在app下新建middlewares.py
# middlewares.py
from django.utils.deprecation import MiddlewareMixin
class MiddleWare(MiddlewareMixin):
def process_response(self, request, response):
response['Access-Control-Allow-Origin'] = "*"
if request.method == 'OPTIONS':
response['Access-Control-Allow-Methods'] = "POST, GET, DELETE, OPTIONS, DELETE"
response['Access-Control-Max-Age'] = 1728000
response["Access-Control-Allow-Headers"] = "Content-Type, x-requested-with"
return response
return response
修改settings
# settings.py
MIDDLEWARE = [
...
'forum.middlewares.MiddleWare',
]
Token
安装Simple JWT
$ pip install djangorestframework-simplejwt
在setting中添加默认鉴权类
REST_FRAMEWORK = {
...
'DEFAULT_AUTHENTICATION_CLASSES': (
...
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
...
}
在urls.py添加对外接口
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
urlpatterns = [
...
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
...
]
创建超级用户
$ python manage.py createsuperuser
# 更改密码
$ python manage.py changepassword [<username>]
用curl获取token
curl \
-X POST \
-H "Content-Type: application/json" \
-d '{"username": "davidattenborough", "password": "boatymcboatface"}' \
http://localhost:8000/api/token/
...
{
"access":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiY29sZF9zdHVmZiI6IuKYgyIsImV4cCI6MTIzNDU2LCJqdGkiOiJmZDJmOWQ1ZTFhN2M0MmU4OTQ5MzVlMzYyYmNhOGJjYSJ9.NHlztMGER7UADHZJlxNG0WSi22a2KaYSfd1S-AuT7lU",
"refresh":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3BrIjoxLCJ0b2tlbl90eXBlIjoicmVmcmVzaCIsImNvbGRfc3R1ZmYiOiLimIMiLCJleHAiOjIzNDU2NywianRpIjoiZGUxMmY0ZTY3MDY4NDI3ODg5ZjE1YWMyNzcwZGEwNTEifQ.aEoAYkSJjoWH1boshQAaTkf8G3yn0kapko6HFRt7Rh4"
}
返回的两个token,access默认5分钟过期,过期后用refresh刷新,refresh默认1天过期,可以在settings修改过期时间
# Django project settings.py
from datetime import timedelta
...
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1)
}
详细使用方法:
https://django-rest-framework-simplejwt.readthedocs.io/en/latest/getting_started.html
Settings 中Debug改为false后static文件404
正式发布时,Debug是要改为false的,否则系统会把所有的请求缓存到内存上,造成进程占用的内存越来越大,而debug=false后,DRF管理界面css样式就获取不到了
简单粗暴的解决方式是
$ python3 manage.py runserver --insecure
这样做和debug=true时类似,效率十分低,且有安全隐患
https://docs.djangoproject.com/en/3.0/ref/contrib/staticfiles/#module-django.contrib.staticfiles
我看了半天,最后的处理方法是发布前collectstatic收集静态文件,把整个文件夹丢到服务器上,修改setting里STATIC_URL为服务器上文件夹存放的目录
$ python3 manage.py collectstatic
其他
# settings.py
# 修改时区
TIME_ZONE = 'Asia/Shanghai'
# 全局分页
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 5 # 每页数目
}
# 设置Shell共享库位置
$ export LD_LIBRARY_PATH="/usr/local/lib"
# 使设置生效
$ source ~/.bashrc
网友评论