一、环境搭建

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

本地安装了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命令:
在这里插入图片描述
查看Django版本命令为:
在这里插入图片描述

四、新建Django项目

1、使用PyCharm创建Django项目

File——》new Project——》Django
在这里插入图片描述

2、项目结构

在这里插入图片描述

3、项目运行结果

在这里插入图片描述

五、优化项目结构

前面创建的项目中,优化项目结构
新建static文件夹cssjs图片等放入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

将以下内容添加到您的settings.py模块中:

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、安装

首选的安装方法直接来自pypi

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进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注