一、环境搭建
IDE:Pycharm
数据库:MySQL、Navicat
Python版本:python 3.9.2
虚拟环境:virtualenvwrapper
1. 安装Python解释器
官网下载:https://www.python.org
建议下载:Python 3.9.2
2. 安装Pycharm
二、Python创建虚拟环境(可以直接指向Python安装的可执行文件,此步可省略)
创建虚拟环境是为了让项目运行在一个独立的局部的Python环境中,使得不同环境的项目互不干扰。
1. 查看本机的Python版本
本地安装了Python 3.9.2,现使用Python3.9.2创建一个虚拟环境。
2. 本地搜索Python 3.9的文件位置
3. Python 3.9 (64-bit) 右键,属性
4. 用命令创建虚拟环境指向Python 3.9,虚拟环境名称为:myapi
pip install virtualenv -i https://pypi.douban.com/simple/
pip install virtualenvwrapper-win -i https://pypi.douban.com/simple/
mkvirtualenv -p C:pythonPython39python.exe myapi
6. 进入虚拟环境
workon myapi
7. 退出虚拟环境
deactivate
三、安装Django
pip install Django==4.1.4 -i https://pypi.douban.com/simple
四、新建Django项目
1、使用PyCharm创建Django项目
2、项目结构
3、项目运行结果
五、优化项目结构
在前面创建的项目中,优化项目结构:
新建static文件夹:css、js、图片等放入static目录下。
新建media文件夹:存放用户上传图片、文件等放到此文件夹中。
新建一个package,命名为apps,将项目myapi放入此文件夹。
新建一个package,命名为extra_apps,将项目添加的第三方源码放入此目录中。
新建一个文件,名称requirements.txt,用于记录项目依赖的第三方包。
六、使用Django REST framework自动生成接口文档环境配置
1、 安装
使用 安装pip,包括您想要的任何可选包…
pip install djangorestframework
pip install markdown # Markdown support for the browsable API.
pip install django-filter # Filtering support
2、 配置
(1)添加’rest_framework’到您的INSTALLED_APPS设置中。
INSTALLED_APPS = [
...
'rest_framework',
]
(2)将以下内容添加到您的根urls.py文件中。
urlpatterns = [
...
path('docs/', include_docs_urls(title='留言板项目接口文档')),
]
(3)settings.py模块中增加全局REST_FRAMEWORK
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
]
}
七、案例(用户管理)
1、创建一个读写 API 来访问我们项目中用户的信息。
(1)新建一个应用users
manage.py@myapi_project > startapp users
(2)将users拖入到apps中
(3)在myapi_projectmyapi_projectsettings.py中增加一行。
INSTALLED_APPS = [
'apps.users.apps.UsersConfig',
]
2、新建MySQL数据库myapi_db
3、修改settings.py中的数据库配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'myapi_db',
'USER': 'root',
'PASSWORD': 'root',
'HOST': '127.0.0.1',
}
}
4、 安装MySQL驱动:
windows下载安装包的网址:
https://www.lfd.uci.edu/~gohlke/pythonlibs/
搜索mysqlclient
根据你Python版本找到相应的mysqlclient版本。此处下载了mysqlclient-1.4.6-cp39-cp39-win_amd64.whl。
找到自己的下载路径:
cd D:mysqlclient驱动安装
workon myapi
安装:
pip install mysqlclient-1.4.6-cp39-cp39-win_amd64.whl
5、修改users models.py
makemigrations
migrate
6、修改users models.py
当使用makemigrations、migrate命令后,数据库中会自动添加了一些表。
因为我们网站中包含用户手机号码注册、登录功能,所以需要在现有的user表中添加一些字段,具体步骤如下。
(1)自定义一张表userprofile
此表保留user表中的字段,再新增如下图所示的一些字段。修改users/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.db.models import DateTimeField
GENDER_CHOICES = (
("male", "男"),
("female", "女")
)
class UserProfile(AbstractUser):
username = models.CharField(max_length=50, verbose_name="用户姓名", null=True, unique=True, default="")
nick_name = models.CharField(max_length=50, verbose_name="昵称", null=True, blank=True, default="")
birthday = models.DateField(verbose_name="生日", null=True, blank=True)
gender = models.CharField(verbose_name="性别", choices=GENDER_CHOICES, max_length=6, default="男", null=True,
blank=True)
address = models.CharField(max_length=100, verbose_name="地址", null=True, blank=True)
email = models.CharField(max_length=100, verbose_name="邮箱", null=True, blank=True)
mobile = models.CharField(max_length=11, verbose_name="手机号码", null=True, blank=True)
image = models.ImageField(upload_to="head_image/%Y/%m", default="default.jpg", verbose_name="用户头像", null=True,
blank=True) # media目录下
date_joined = DateTimeField(auto_now_add=True)
# 通过一个内嵌类 "class Meta" 可以给model定义元数据
# verbose_name指定在admin管理界面中显示中文;
# verbose_name表示单数形式的显示,verbose_name_plural表示复数形式的显示;中文的单数和复数一般不作区别。
class Meta:
verbose_name = "用户信息"
verbose_name_plural = verbose_name
# 平常创建一个类的对象,print这个对象时一般会是这个对象的所属类和内存地址;
# 我们改写类中的__str__方法后可以在print时得到想要的易于人阅读的对象的信息
def __str__(self):
if self.nick_name:
return self.nick_name
else:
return self.username # username是必填字段,不能为空
(2)先删除数据库中的所有表。
(3)安装pillow包
pip install pillow
(4)在settings.py文件中指名使用的用户表
AUTH_USER_MODEL = "users.UserProfile" # app的名称加上类名
(5)分别执行makemigrations、migrate
makemigrations
migrate
此时数据库中的表已发生了变化
userprofile表的结构:
7、在apps/users下新建一个serializers.py:
from rest_framework import serializers
from apps.users.models import UserProfile
class UserProfileSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = UserProfile
fields = ['id', 'password', 'last_login', 'is_superuser', 'username', 'first_name',
'last_name', 'email', 'is_staff', 'is_active', 'date_joined', 'nick_name',
'birthday', 'gender', 'address', 'mobile', 'image']
8、修改apps/users/views.py
import json
from django.contrib.auth import authenticate, login, logout
from django.http import JsonResponse, HttpResponse
from django.shortcuts import render, redirect
from django.views.decorators.csrf import csrf_exempt
from rest_framework import viewsets, permissions
from . import models
from .models import UserProfile
from .serializers import UserProfileSerializer
class UserProfileViewSet(viewsets.ModelViewSet):
queryset = UserProfile.objects.all().order_by('id')
serializer_class = UserProfileSerializer
permission_classes = [permissions.IsAuthenticated]
# @api_view(['POST'])
# 忽略csrf校验
@csrf_exempt
# @api_view(['GET', 'POST'])
def register_view(request):
if request.method == 'POST':
meta = {
"msg": "用户注册成功!",
"status": 200
}
form_data = json.loads(request.body.decode("UTF-8"))
username = form_data['username']
exists = UserProfile.objects.filter(username=username).exists()
if exists:
edit_obj = models.UserProfile.objects.get(username=username)
else:
edit_obj = UserProfile.objects.create_user(username=username)
edit_obj.username = form_data['username']
edit_obj.set_password(form_data['password'])
edit_obj.gender = form_data['gender']
edit_obj.email = form_data['email']
edit_obj.address = form_data['address']
edit_obj.mobile = form_data['mobile']
edit_obj.image = form_data['image']
edit_obj.save()
if exists:
meta = {
"msg": "用户信息修改成功!",
"status": 200
}
data = {
"user_id": edit_obj.id,
"username": edit_obj.username,
"mobile": edit_obj.mobile,
"exists": exists
}
return JsonResponse({
'meta': meta,
'data': data
})
if request.method == 'GET':
data = {}
meta = {
"msg": "新用户进入用户注册界面!",
"status": 200
}
form_data = json.loads(request.body.decode("UTF-8"))
if form_data is not None:
username = form_data['username']
exists = UserProfile.objects.filter(username=username).exists()
if exists:
edit_obj = models.UserProfile.objects.get(username=username)
data.update({"username": username})
data.update({"password": edit_obj.password})
data.update({"gender": edit_obj.gender})
data.update({"email": edit_obj.email})
data.update({"address": edit_obj.address})
data.update({"mobile": edit_obj.mobile})
data.update({"image": str(edit_obj.image)})
meta = {
"msg": "用户信息查询成功!",
"status": 200
}
return JsonResponse({
'meta': meta,
'data': data
})
@csrf_exempt
def login_view(request):
form_data = json.loads(request.body.decode("UTF-8"))
username = form_data['username']
data = {}
if request.method == 'POST':
password = form_data['password']
try:
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
meta = {
"msg": "登录成功",
"status": 200
}
data = {
"user_id": user.id,
"username": username,
"mobile": user.mobile
}
else:
meta = {
"msg": "用户名或密码错误",
"status": 422
}
except:
meta = {
"msg": "用户名或密码错误",
"status": 422
}
return JsonResponse({
'meta': meta,
'data': data
})
# 修改超级管理员密码
@csrf_exempt
def change_password(request):
exists = UserProfile.objects.filter(username='admin').exists()
if exists:
user = models.UserProfile.objects.get(username='admin')
user.set_password('admin')
user.save()
print(user.password)
return HttpResponse("密码修改成功")
else:
return HttpResponse("对不起,没有该用户")
# 注销接口
@csrf_exempt
# @api_view(['GET', 'POST'])
def logout_view(request):
logout(request)
return redirect('login')
9、修改项目根urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from rest_framework.documentation import include_docs_urls
from apps.users.views import UserProfileViewSet, register_view, login_view, logout_view, change_password
# 生成接口文档使用
router = routers.DefaultRouter()
router.register(r'users', UserProfileViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)), # 自动生成接口文档
path('api-auth/', include('rest_framework.urls')),
path('docs/', include_docs_urls(title='项目接口文档')), # 自动生成接口文档
path('register/', register_view, name='register'),
path('login/', login_view, name='login'),
path('logout/', logout_view, name='logout'),
path('change_password/', change_password, name='change_password'),
]
10、添加配置settings.py
# 请在MIDDLEWARE中增加一行注释
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',
]
# 修改语言和时区
LANGUAGE_CODE = 'zh-hans'
USE_TZ = False
TIME_ZONE = 'Asia/Shanghai'
# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai' # 时区
USE_I18N = True
USE_TZ = True
# 接口文档
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}
# 所有域名都可以跨域访问
CORS_ORIGIN_ALLOW_ALL = True
11、使用Postman测试接口
(1)postman使用csrftoken
使用postman时,如果项目开启了csrf防护,需要在请求的header中加入“X-CSRFToken”,
1)header头部分别加入Content-Type(根据实际情况设置)和x-csrf-token,{{csrftoken}如下图:
(2)注册接口
{
"password": "good",
"last_login": "",
"is_superuser": false,
"username": "good",
"first_name": "",
"last_name": "",
"email": "admin@qq.com",
"is_staff": true,
"is_active": true,
"date_joined": null,
"nick_name": "",
"birthday": null,
"gender": "男",
"address": null,
"mobile": null,
"image": null
}
(3)登录接口
七、案例(公告管理)
1、创建一个读写 API 来访问我们项目中用户的信息。
(1)新建一个应用notices
manage.py@myapi_project > startapp notices
(2)将notices拖入到apps中
(3)在myapi_projectmyapi_projectsettings.py中增加一行。
INSTALLED_APPS = [
'apps.notices.apps.NoticesConfig',
]
2、编辑model
myapi_projectappsnoticesmodels.py
from datetime import datetime
from django.db import models
from apps.users.models import UserProfile
class BaseModel(models.Model):
add_time = models.DateTimeField(default=datetime.now, verbose_name="添加时间")
class Meta:
abstract = True
class Notice(BaseModel):
title = models.CharField(max_length=50, verbose_name="公告标题", null=True, unique=True, default="")
content = models.CharField(max_length=500, verbose_name="公告内容", null=True, blank=True)
user = models.ForeignKey(UserProfile, on_delete=models.CASCADE, verbose_name="发布人")
class Meta:
verbose_name = "公告信息"
verbose_name_plural = verbose_name
3、同步数据库
makemigrations
migrate
4、在apps/notices下新建一个serializers.py:
from rest_framework import serializers
from apps.notices.models import Notice
class NoticeSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Notice
fields = ['id', 'add_time', 'title', 'content', 'user_id']
5、修改apps/notices/views.py
http://127.0.0.1:8000/notices/
http://127.0.0.1:8000/notices/1/
http://127.0.0.1:8000/add_notice/
http://127.0.0.1:8000/delete_notice/1/
http://127.0.0.1:8000/edit_notice/
八、drf-yasg: 从Django REST框架代码自动生成真正的Swagger/openapi2.0模式
1、安装
pip install -U drf-yasg
另外,如果您想使用built-in验证机制(参见4。验证),您需要安装一些额外的要求:
pip install -U drf-yasg[validation]
2、In settings.py:
INSTALLED_APPS = [
...
'drf_yasg',
...
]
3、In urls.py:
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="平台API文档",
default_version='v1',
description="Welcome to ***",
# terms_of_service="https://www.tweet.org",
# contact=openapi.Contact(email="demo@tweet.org"),
# license=openapi.License(name="Awesome IP"),
),
public=True,
# 我也添加了此处但是还是有权限问题
permission_classes=(permissions.AllowAny,),
)
urlpatterns = [
# 对测试人员更友好
path('doc/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
# 对开发人员更友好
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
...
]
4、文档地址
http://127.0.0.1:8000/doc/
http://127.0.0.1:8000/redoc/
原文地址:https://blog.csdn.net/boxuestudio/article/details/128906745
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_24734.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!