【测试平台学习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.
原文地址:https://www.cnblogs.com/Ronaldo-HD/p/14420093.html