前言
上一章,我学习到建自己的业务模块了,今天我们继续学习,djangoAdmin的使用,配置自己的业务后端界面,以及提供python接口供调用
一、models.py与数据库表
上一张讲到我们自己的业务模块时通过命令执行,一次性建立的,相关py文件就都生成了。那么现在怎么补充models.py的内容呢?
先说正向生成:
- 正向生成(models.py生成/更新表)
1、将app加到settings的INSTALLED_APPS里
打开Terminal命令框,执行命令
2、执行:python manager.py makemigrations
3、执行:python manager.py migrate
这个我觉得其实是搞反了,凡是大型项目、平台貌似都应该先有数据库、表。最记得的是以前的老师说,一般数据库设计占40%时间(我感觉不是什么大厂都不会这样的,一般公司DBA都没有)
- 反向生成(根据表生成models.py)
打开Terminal命令框,执行命令
python 主启动py inspectdb [–database 数据库名] 表名 > 模块名称\models.py
python manage.py inspectdb user_info > .\user\models.py
python manage.py inspectdb --database db2 user (多数据库连接时可指定库名)
二、配置djangoAdmin的业务模块后台界面
1.先看效果
代码就是几个文件的修改,我都写了注释,都是一些常用的,更多就要自己看django-admin的官方Api了,代码我毫无保留的全贴,大家可以自行注释逐个查看效果,最后我在总加几个常见的坑。
2.码上见真章
- models.py(这个感觉就类似JAVA里的mybatis的xml文件)
# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
# * Rearrange models' order
# * Make sure each model has one field with primary_key=True
# * Make sure each ForeignKey and OneToOneField has `on_delete` set to the desired behavior
# * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
from django import forms
from django.contrib.auth.hashers import make_password
from django.db import models
class UserInfo(models.Model):
id = models.AutoField(verbose_name='主键', primary_key=True, unique=True)
name = models.CharField(verbose_name='姓名', max_length=200, blank=True, null=True)
mobile = models.CharField(verbose_name='手机号', max_length=20, blank=True, null=True)
# 性别
sexChoices = (
(1, '男'), (0, '女')
)
sex = models.IntegerField(verbose_name='性别', blank=True, choices=sexChoices, null=True)
nickname = models.CharField(verbose_name='昵称', max_length=30, null=True)
password = models.CharField(verbose_name='密码', max_length=128, default='')
salt = models.CharField(verbose_name='盐值', max_length=10, default='123456')
memo = models.CharField(verbose_name='备注', max_length=500, blank=True, null=True)
create_by = models.IntegerField(verbose_name='创建人ID', blank=True, null=True)
create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True, blank=True, null=True)
delChoices = ((0, '否'), (1, '是'))
is_deleted = models.IntegerField(verbose_name='是否删除', default=0, choices=delChoices, blank=True, null=True)
# 关联查询时返回内容
def natural_key(self):
return {
"id": str(self.id),
"name": str(self.name),
'nickname': str(self.nickname),
"mobile": str(self.mobile),
"sex": str(self.sex)
}
class Meta:
managed = False
db_table = 'user_info'
ordering = ['-create_time'] #admin的列表有设置排序时优先,如果没有设置就默认这里的排序规则
verbose_name = '用户信息'
verbose_name_plural = '用户信息'
# 修改&添加提交时被执行,对密码进行加密
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
if len(str(self.salt)) == 0:
self.salt = self.password
# 密码加密,使用盐值加密
self.password = make_password(self.password, self.salt)
super().save(force_insert=False, force_update=False, using=None, update_fields=None)
- apps.py(类似spring的bean注册、定义)
这里不设置,在settings.pyl里是INSTALLED_APPS是引入不了这个模块的。
- admin.py(django-admin的界面配置文件)
from django.contrib import admin
# Register your models here.
from django.utils.html import format_html
from user.models import UserInfo
@admin.register(UserInfo)
class UserInfoAdmin(admin.ModelAdmin):
# 列表展示列参数
# 1、显示的列表信息
list_display = ('name', 'nickname', 'mobile', 'sex', 'salt', 'create_time')
# 2、查询过滤字段
list_filter = ('sex',)
# 3、搜索的字段
search_fields = ('name', 'nickname', 'mobile')
# 4、可编辑的字段
list_editable = ('mobile', 'nickname', 'sex')
# 5、后台只读字段
readonly_fields = ('create_time', 'create_by')
# 6、后台表格重可点击跳转到修改页面的字段,默认时list_display中的第一个字段
list_display_links = ('name',)
# 7、分页、每页显示条数
list_per_page = 10
# 8、分页、显示全部(真实数据 < 该值时,才会有显示全部)
list_max_show_all = 15
# 9、默认排序(默认升序,字段前-表示降序)
#ordering = ('id', '-create_time')
# 10、是否显示选择个数
actions_selection_counter = True
# 11、模糊搜索是否显示结果的个数
show_full_result_count = True
# 12、自定义字段、如:
def pic_img(self, obj):
return format_html('<img src="%s" width="50px"/>' % (obj.pic,))
# 该字段的名称
pic_img.short_description = '主图'
pic_img.allow_tags = True
# 详情页参数
# 1、详情页需要显示的字段
# fields = ('name', 'mobile', 'sex', 'create_time')
# 2、分组显示详情页
fieldsets = (
('基本信息', {
'fields': ('name', 'nickname', 'sex', 'password')}), ('联系方式', {
'fields': ('mobile',)}),
('其他信息', {
'fields': ('salt', 'create_time')}))
# 3、详情页面需要排除的字段
exclude = ('create_by',)
# 4、详情页面:删除、修改、更新后跳转回列表后,是否保留原搜索条件
preserve_filters = True
# 5、详情页面:是否显示保存、删除等按钮
save_on_top = True
# 6、详情页:"保存并增加另一个"和"保存并继续编辑"
# save_as = True,save_as_continue = True,保存后继续编辑
# save_as = True,save_as_continue = False,保存后返回列表
save_as = True
# 点击保存并继续编辑
save_as_continue = True
# 7、详细多对多时多选框、样式好看
# filter_vertical = ('gallery',)
# filter_horizontal = ('gallery', )
# 8、详情页在外键的地方使用单选框来实现选择
# radio_fields = {'pic':admin.VERTICAL}
# radio_fields = {'pic': admin.HORIZONTAL}
小结:
1、django-admin要看到界面,基本上就是上面的3个文件的配置
2、复杂应用用django-admin配置管理后端有点够呛
3、命令反向生成models.py可能改变文件编码,启动会报错:
修改文件编码就可以了,pyCharm修改为UTF-8
三、提供接口
这里就正式开始提供接口,不管你是前端还是后端调用(没有接口权限校验)
所有接口写在views.py里。
views.py
import json
from django.core import serializers
from django.core.paginator import Paginator
from django.http import JsonResponse
from django.shortcuts import render
# Create your views here.
# @csrf_exempt表示视图可以进行跨域请求
from django.views.decorators.csrf import csrf_exempt
from user.models import UserInfo
@csrf_exempt
def userList(request):
print(request.method)
# 统一响应对象
response = {
'code': 200,
'success': True,
'msg': '成功'
}
try:
body = json.loads(request.body.decode("utf-8"))
# 请求参数
param = {
}
param['page'] = body['page']
param['size'] = body['size']
param['name'] = body['name']
param['mobile'] = body['mobile']
# 数据
list = UserInfo.objects.all()
# 查询数据:模糊查询
if param['name'] is not None:
list = list.filter(name__contains=param['name'])
if param['mobile'] is not None:
list = list.filter(mobile__contains=param['mobile'])
# 分页插件
paginator = Paginator(list, param['size'])
# 获取总条数
response['total'] = paginator.count
# 获取当前页数据集合
records = paginator.page(param['page'])
# 将数据序列化为json对象,并且关联查询外键的数据
response['data'] = json.loads(serializers.serialize('json', records, use_natural_foreign_keys=True))
except:
response['data'] = ''
response['code'] = 500
response['msg'] = '失败'
# 响应结果对象
return JsonResponse(response)
配置路由(接口地址)
python目前这点是我最满意的,接口都是显示的,不用像java那样找swagger还对代码有侵入(不过这里也是仅仅只能看到接口的url,至于参数还是看不到的)
"""zwDjangoProject URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.0/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path, include, re_path
from django.views.static import serve
from user import views as user_views
urlpatterns = [
path('admin/', admin.site.urls),
re_path(r'upload/(?P<path>.*)$', serve, {
'document_root': 'upload'}),
re_path('userList', user_views.userList)
]
postman请求接口:
后端断点调试截图
还有详细信息大家可以自己看对象。
PS:
1、这里的数据库查询还没有上ORM框架,不知道有没有类似mybatis的tk、plus这种,可以支持自行写sql
2、这里要说的就是这个看到的sql复制后,直接在mysql的客户端工具执行会报错,这感觉特别不利于检查业务逻辑的sql是否合理(希望有类似java的mybatisX的插件)
有博友说在settings.py里增加日志配置,可以看到sql,但是我看了,那sql复制出来到数据库客户端也是执行不了的。
增加配置到settings.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}
四、总结
- 插件推荐
Kite AI Code :代码提示,还是特别香的。这个免费的,土豪可以装Auto Python Code Suggestions
GitToolBox:可以看到每一行代码提交信息,team扯皮执法官
Ruirements:让依赖文件能高亮显示 - 阶段感想
1、找反向生成models.py的插件没有找到(不想输命令,如果有高能知道麻烦留言告知下)
2、django-admin做轻量级后端还行,复杂、好看的用这个够呛
3、好多插件没有,比如反向生成models.py的插件
4、感觉做web的后端提供api接口有点鸡肋 - 下一目标
1、引入Restful Api支持
2、ORM框架
3、python的事务
希望能帮到大家,我们一起卷,卷卷更健康,加油技术人,欧利给!!!!