python卷java实现api接口提供(二)

前言

上一章,我学习到建自己的业务模块了,今天我们继续学习,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的事务
    希望能帮到大家,我们一起卷,卷卷更健康,加油技术人,欧利给!!!!

猜你喜欢

转载自blog.csdn.net/zwrlj527/article/details/122238097