前言
最近打算使用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
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无效"})
四、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.