• 【测试平台学习2】 Django 的初使用


    前言

    最近打算使用Django+Vue 打造一个简单的测试平台,本文对django 的使用略做记录

    Django的安装与背景

    Python 的后端主要有Django 和flask , 我对此只有粗浅的理解和认识, 使用flask 编写过一个接口Mock系统, flask是轻量化的,能快速实现接口的开发工作,但是它没有自带数据库。

    Django 相对比较全面,自带数据库sqlite(当然也可以连接其他数据库,例如mysql), 另外Django 可以很方便的进行路由分配,数据缓存等等。

    MVT模式:前后端分离,高内聚低耦合,

    • m:model,与mvc中的m功能相同,负责和数据库交互,进行数据处理,
    • v:view,与mvc中的c功能相同,接收请求,进行业务处理,返回应答,                
    • t:template,与mvc中的v功能相同,负责封装构造要返回的html。

    Django的简单开发流程

    一、Django项目的初始化

    在Django中通常一个功能的开发顺序为:创建应用 -> 数据库表字段设计 -> 视图函数编写 -> 应用路由 -> 全局路由 -> 测试

    白话版本:  1. 建表并迁移 --- 2. 在应用下面编写底层逻辑 --- 3. 配置应用路由和全局路由

    1. 创建一个Django项目 (这里我用的pycharm)

    2. 创建你的django应用 (例如用户登录、注册功能)

        2.1 命令行方式创建  python manage.py [your app name]

        2.2 工具方式创建- 在pycharm里面选择 Tools > Run manage.py Task… 然后执行: startapp [your app name]

    3. 应用注册 ./settings.py文件里名为INSTALLED_APPS的列表中

    4. django应用目录详解

    users
     ├── migrations  # 存放迁移数据表的历史文件,内容自动生成
     │    └── __init__.py  # 一个空文件,告诉 Python 该目录是一个 Python 包。
     ├── __init__.py  # 一个空文件,告诉 Python 该目录是一个 Python 包。
     ├── admin.py  # 该应用的后台管理系统配置,这里用不到
     ├── apps.py    # 该应用的一些配置,这里用不到
     ├── models.py    # 数据模块,用来定义数据表结构
     ├── tests.py    # Django提供的自动化测试功能,这里用不到
     └── views.py    # 视图模块,代码逻辑处理的主要地点,项目中大部分代码均在这里编写

    二、Django数据库表的处理过程

    5. 编写数据模型【数据库的公共字段,用于创建数据库表时候继承用】

       路径:  ./utils/base_models.py

    from django.db import models
    
    
    class BaseModel(models.Model):
        """
        数据库表公共字段
        """
        create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间', help_text='创建时间')
        update_time = models.DateTimeField(auto_now=True, verbose_name='更新时间', help_text='更新时间')
        is_delete = models.BooleanField(default=False, verbose_name='逻辑删除', help_text='逻辑删除')
    
        class Meta:
            # abstract = True:为抽象模型类,用于其他模型类继承,数据库迁移时不会创建ModelBase表
            abstract = True
            verbose_name = '公共字段表'
            db_table = 'BaseModel'

    6. 编写数据库表,继承上面的类

    from django.db import models
    
    from utils.base_models import BaseModel
    
    
    class Users(BaseModel):
        id = models.AutoField(primary_key=True, verbose_name='id主键')
        username = models.CharField(max_length=50, unique=True, verbose_name='用户名')
        password = models.CharField(max_length=50, verbose_name='密码')
        email = models.EmailField(max_length=50, verbose_name='邮箱')
    
        def __str__(self):
            return self.username
    
        class Meta:
            db_table = 'test_users'
            verbose_name = '用户数据'
            verbose_name_plural = verbose_name

    7. 数据库新建表的迁移

        7.1 使用命令行方式迁移

        python manage.py makemigrations

        python manage.py migrate

        7.2或者再pycharm下面: 选择 Tools > Run manage.py Task… 然后执行: 

        makemigrations

        migrate

        7.3 迁移某个具体的app数据库表:

        python manage.py makemigrations 【app name】

        python manage.py migrate 【app name】

        

    8. 数据库模型类在admin.py中注册 【这一步不做,数据库表也能生效,具体功能待研究】

        

    三、Django视图部分的编写 

    9. 编写视图函数 (下面是一个用户注册,登录的表单提交逻辑,可以放在./users/forms.py)

    import re
    
    from django import forms
    from django.core.exceptions import ValidationError
    
    from users.models import Users
    
    
    class RegisterForm(forms.Form):
        username = forms.CharField(
            label="用户名",
            required=True,
            max_length=50,
            min_length=2,
            error_messages={
                "required": "用户名不能为空",
                "max_length": "用户名最长不能超过50个字符",
                "min_length": "用户名最小长度为2"
            })
        password = forms.CharField(
            label="密码",
            required=True,
            max_length=50,
            min_length=5,
            error_messages={
              "required": "密码不能为空",
              "max_length": "密码最长不能超过50个字符",
              "min_length": "密码最小长度为5"
            })
        r_password = forms.CharField(
            required=True,
            max_length=50,
            min_length=5,
            label="确认密码",
            error_messages={
                "required": "确认密码不能为空",
                "max_length": "确认密码最长不能超过50个字符",
                "min_length": "确认密码最小长度为5"
            })
        email = forms.CharField(
            min_length=5,
            required=True,
            label="邮箱",
            error_messages={
                "required": "邮箱不能为空",
                "max_length": "邮箱最长不能超过50个字符",
                "min_length": "邮箱最小长度为5"
            }
        )
    
        def clean_username(self):
            val = self.cleaned_data.get("username")
            ret = Users.objects.filter(username=val)
            if not ret:
                return val
            else:
                raise ValidationError("该用户名已注册!")
    
        def clean_email(self):
            val = self.cleaned_data.get("email")
            if re.match(r'^[0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}.[com,cn,net]{1,3}$', val):
                return val
            else:
                raise ValidationError("邮箱格式不正确!")
    
        # 走完所有的校验才走clean
        def clean(self):
            pwd = self.cleaned_data.get("password")
            r_pwd = self.cleaned_data.get("r_password")
            if pwd and r_pwd:
                if pwd != r_pwd:
                    raise forms.ValidationError("两次密码不一致")
            return self.cleaned_data
    View Code

    10. 编写views.py (./users/views.py  应用的逻辑处理部分,可调用上一步的视图函数)

    # users/views.py
    from django.http import JsonResponse
    from django.views import View
    
    from users.forms import RegisterForm
    from users.generate_token import generate_jwt_token
    from users.models import Users
    from utils.jwt_permission_required import auth_permission_required
    from utils.common import result
    
    
    class LoginView(View):
        def post(self, request):
            result["message"] = "登录失败"
            result["success"] = False
            result["details"] = None
            json_data = request.body.decode('utf-8')
            if json_data:
                python_data = eval(json_data)
                username = python_data.get('username')
                password = python_data.get('password')
                data = Users.objects.filter(username=username, password=password).values("id", "username").first()
                if data:
                    token = generate_jwt_token(username)
                    result["message"] = "登录成功"
                    result["success"] = True
                    result["details"] = {"id": data["id"], "username": data["username"],"token": token}
                    return JsonResponse(result, status=200)
                result["details"] = "用户名或密码错误"
                return JsonResponse(result, status=400)
            return JsonResponse(result, status=500)
    
    
    class RegisterView(View):
        def post(self, request):
            result["message"] = "注册失败"
            result["success"] = False
            result["details"] = None
            json_data = request.body.decode('utf-8')
            if json_data:
                python_data = eval(json_data)
                data = RegisterForm(python_data)
                if data.is_valid():
                    data.cleaned_data.pop("r_password")
                    Users.objects.create(**data.cleaned_data)
                    data.cleaned_data.pop("password")
                    result["message"] = "注册成功"
                    result["success"] = True
                    result["details"] = data.cleaned_data
                    return JsonResponse(result, status=200)
                else:
                    result["details"] = data.errors
                    return JsonResponse(result, status=400)
            return JsonResponse(result, status=500)
    
    @auth_permission_required("func")
    def demo(request):
        if request.method == 'GET':
            return JsonResponse({"state": 1, "message": "token有效"})
        else:
            return JsonResponse({"state": 0, "message": "token无效"})
    View Code

    四、Django路由设置

    11. 编写应用的路由

    #users/urls.py
    from django.urls import path
    
    from users import views
    
    urlpatterns = [
        path('login', views.LoginView.as_view()),
        path('register', views.RegisterView.as_view()),
        path('demo', views.demo)
    ]

    12. 加入全局路由

    # testplatform/urls.py
    from django.contrib import admin
    from django.urls import path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('api/user/', include("users.urls")),
    ]

     五、Django服务启动

     命令行方式启动: python manage.py runserver 127.0.0.1:8001

    看到如下信息时,代表你的django应用启动成功, 可以直接用Postman等工具进行接口调试。

    System check identified no issues (0 silenced).
    February 20, 2021 - 09:15:21
    Django version 2.0.2, using settings 'api_test_master.settings'
    Starting development server at http://127.0.0.1:8001/
    Quit the server with CTRL-BREAK.
  • 相关阅读:
    echarts仪表盘如何设置图例(legend)
    js上传限制文件大小
    js下载文件及命名(兼容多浏览器)
    为什么每个浏览器都有Mozilla字样(转载于知乎shadow)
    用JS做一个简单的电商产品放大镜功能
    unity下跨平台excel读写
    无限大地图:lightmap拆分
    Unity 打包总结和资源的优化和处理
    Unity3d: 资源释放时存储空间不足引发的思考和遇到的问题
    profiler内存优化:警惕回调函数
  • 原文地址:https://www.cnblogs.com/Ronaldo-HD/p/14420093.html
Copyright © 2020-2023  润新知