Python进阶篇(二)-- Django 深入模型

news2025/2/24 18:22:49

        上一节提到了Django是基于MVC架构的Web框架,MVC架构追求的是“模型”和“视图”的解耦合。所谓“模型”说得更直白一些就是数据(的表示),所以通常也被称作“数据模型”。在实际的项目中,数据模型通常通过数据库实现持久化操作,而关系型数据库在过去和当下都是持久化的首选方案,下面我们通过完成一个投票项目来讲解和模型相关的知识点。投票项目的首页会展示某在线教育平台所有的学科;点击学科可以查看到该学科的老师及其信息;用户登录后在查看老师的页面为老师投票,可以投赞成票和反对票;未登录的用户可以通过登录页进行登录;尚未注册的用户可以通过注册页输入个人信息进行注册。在这个项目中,我们使用MySQL数据库来实现数据持久化操作。

1 ORM模型

1.1 ORM介绍

对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。

        简单的说,ORM 是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。ORM 在业务逻辑层和数据库层之间充当了桥梁的作用。ORM 解决的主要问题是对象和关系的映射。它通常把一个类和一个表一一对应,类的每个实例对应表中的一条记录,类的每个属性对应表中的每个字段,具体如下图所示。ORM 提供了对数据库的映射,不用直接编写 SQL 代码,只需像操作对象一样从数据库操作数据。让软件开发人员专注于业务逻辑的处理,提高了开发效率。

        ORM 模式也是有一定缺点的,它会在一定程度上牺牲程序的执行效率。此外,还存在许多复杂场景是 ORM 模式无法解决的,同样还是需要手动编写 SQL 语句完成。

1.2 创建 Django 项目

        首先创建Django项目vote,在项目下创建名为polls的应用和保存模板页的文件夹tempaltes,项目文件夹的结构如下所示。

        根据上面描述的项目需求,这里准备了四个静态页面,分别是展示学科的页面subjects.html,显示学科老师的页面teachers.html,登录页面login.html,注册页面register.html,稍后我们会将静态页修改为Django项目所需的模板页。

1.3 数据库中生成模型表

        在 Django 中,一个模型(model)会映射到一个数据库表。每个模型都是一个 Python 类,它是django.db.models.Model 的子类,模型的每个属性都代表一个数据库字段。

(1) 在 polls 中添加数据模型

        在 polls 的 models.py 中添加如下代码:

from django.db import models        # 引入Django.db.models模块


class Subject(models.Model):
    """
    编写Subject模型类,数据模型应该继承于models.Model或其子类
    """
    no = models.AutoField(primary_key=True, verbose_name='编号')
    name = models.CharField(max_length=50, verbose_name='名称')
    intro = models.CharField(max_length=1000, verbose_name='介绍')
    is_hot = models.BooleanField(verbose_name='是否热门')

    def __str__(self):
        return self.name

    class Meta:
        # 通过db_table自定义数据表名
        db_table = 'tb_subject'


class Teacher(models.Model):
    """
    编写Teacher模型类,数据模型应该继承于models.Model或其子类
    """
    sex_choices = (
        (0, '女'),
        (1, '男'),
    )
    no = models.AutoField(primary_key=True, verbose_name='编号')
    name = models.CharField(max_length=20, verbose_name='姓名')
    sex = models.BooleanField(default=True, verbose_name='性别', choices=sex_choices)
    birth = models.DateField(verbose_name='出生日期')
    intro = models.CharField(max_length=1000, verbose_name='个人介绍')
    photo = models.ImageField(max_length=255, verbose_name='照片')
    gcount = models.IntegerField(default=0, db_column='gcount', verbose_name='好评数')
    bcount = models.IntegerField(default=0, db_column='bcount', verbose_name='差评数')
    sno = models.ForeignKey(Subject, on_delete=models.CASCADE, db_column='sno')

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'tb_teacher'

        Subject 和 Teacher 模型中的每一个属性都指明了models下面的一个数据类型,代表了数据库中的一个字段。上面的类在数据库中会创建如下的表,见1.3节的第二步创建表格的过程。

(2) 迁移模型
        使用 Django 给我们提供的两个命令来在数据库中生成 polls 应用下定义的数据模型,第一步生成迁移文件,第二步将迁移文件应用到数据库:

python manage.py makemigrations
python manage.py migrate

1.3 自动生成数据模型

1. 配置关系型数据库MySQL

(1) 在MySQL中创建数据库,创建用户,授权用户访问该数据库。

create database vote default charset utf8;
create user 'username'@'%' identified by 'yourpassword';
grant all privileges on vote.* to 'username'@'%';
flush privileges;

(2) 在 MySQL 中创建保存学科和老师信息的二维表(保存用户信息的表稍后处理)。

use vote;

-- 创建学科表
create table `tb_subject`
(
	`no` integer auto_increment comment '学科编号',
    `name` varchar(50) not null comment '学科名称',
    `intro` varchar(1000) not null default '' comment '学科介绍',
    `is_hot` boolean not null default 0 comment '是不是热门学科',
    primary key (`no`)
);
-- 创建老师表
create table `tb_teacher`
(
    `no` integer auto_increment comment '老师编号',
    `name` varchar(20) not null comment '老师姓名',
    `sex` boolean not null default 1 comment '老师性别',
    `birth` date not null comment '出生日期',
    `intro` varchar(1000) not null default '' comment '老师介绍',
    `photo` varchar(255) not null default '' comment '老师照片',
    `gcount` integer not null default 0 comment '好评数',
    `bcount` integer not null default 0 comment '差评数',
    `sno` integer not null comment '所属学科',
    primary key (`no`),
    foreign key (`sno`) references `tb_subject` (`no`)
);

(3) 安装数据库的驱动,Python 3.x 使用 pymysql 作为 MySQL的驱动,然后在Django项目文件夹的__init__.py中添加如下所示的代码:

import pymysql
pymysql.install_as_MySQLdb()        # 为了pymysql发挥最大数据库操作性能

         温馨提示: 如果使用Django 2.2及以上版本,还会遇到PyMySQL跟Django框架的兼容性问题,兼容性问题会导致项目无法运行,需要按照GitHub上PyMySQL仓库Issues中提供的方法进行处理。总体来说,使用pymysql会比较麻烦,强烈建议大家首选安装mysqlclient,mysqlclient执行效率也比较高。

(4) 修改项目的settings.py文件,首先将我们创建的应用polls添加已安装的项目(INSTALLED_APPS)中,然后配置MySQL作为持久化方案。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'polls',     # 把应用文件加入
]

ATABASES = {
    'default': {
        # 数据库引擎配置
        'ENGINE': 'django.db.backends.mysql',
        # 数据库的名字
        'NAME': 'vote',
        # 数据库服务器的IP地址(本机可以写为localhost或127.0.0.1)
        'HOST': 'localhost',
        # 启动MySQL服务的端口号
        'PORT': 3306,
        # 数据库用户名和口令
        'USER': 'carpediem',
        'PASSWORD': 'carpediem2021',
        # 数据库使用的字符集
        'CHARSET': 'utf8',
        # 数据库时间日期的时区设定
        'TIME_ZONE': 'Asia/Chongqing',
    }
}

        在配置ENGINE属性时,常用的可选值包括:

  • 'django.db.backends.sqlite3':SQLite嵌入式数据库。
  • 'django.db.backends.postgresql':BSD许可证下发行的开源关系型数据库产品。
  • 'django.db.backends.mysql':甲骨文公司经济高效的数据库产品。
  • 'django.db.backends.oracle':甲骨文公司关系型数据库旗舰产品。

        其他的配置可以参考官方文档中的数据库配置部分。

(5) Django框架提供了ORM来解决数据持久化问题,ORM翻译成中文叫“对象关系映射”。因为Python是面向对象的编程语言,我们在Python程序中使用对象模型来保存数据,而关系型数据库使用关系模型,用二维表来保存数据,这两种模型并不匹配。使用ORM是为了实现对象模型到关系模型的双向转换,这样就不用在Python代码中书写SQL语句和游标操作,因为这些都会由ORM自动完成。利用Django的ORM,我们可以直接将刚才创建的学科表和老师表变成Django中的模型类。

python manage.py inspectdb > polls/models.py

我们可以对自动生成的模型类稍作调整,代码如下所示。

from django.db import models


class Subject(models.Model):
    no = models.AutoField(primary_key=True, verbose_name='编号')
    name = models.CharField(max_length=50, verbose_name='名称')
    intro = models.CharField(max_length=1000, verbose_name='介绍')
    is_hot = models.BooleanField(verbose_name='是否热门')

    class Meta:
        managed = False
        db_table = 'tb_subject'


class Teacher(models.Model):
    no = models.AutoField(primary_key=True, verbose_name='编号')
    name = models.CharField(max_length=20, verbose_name='姓名')
    sex = models.BooleanField(default=True, verbose_name='性别')
    birth = models.DateField(verbose_name='出生日期')
    intro = models.CharField(max_length=1000, verbose_name='个人介绍')
    photo = models.ImageField(max_length=255, verbose_name='照片')
    gcount = models.IntegerField(default=0, db_column='gcount', verbose_name='好评数')
    bcount = models.IntegerField(default=0, db_column='bcount', verbose_name='差评数')
    sno = models.ForeignKey(Subject, models.DO_NOTHING, db_column='sno')

    class Meta:
        managed = False
        db_table = 'tb_teacher'

        若你的确想要允许 Django 管理这些表格的生命周期,你需要将上面的 managed 选项的值改为 True (或者删掉它,因为 True 是默认值)

         温馨提示: 所有模型都是django.db.models.Model类的子类,模型类跟关系型数据库的二维表对应,模型对象跟表中的记录对应,模型对象的属性跟表中的字段对应。每个字段由django.db.models.Field子类(内置在Django core)的实例表示,它们并将被转换为数据库的列。

        该功能仅是一个快捷方式,不是最佳的创建模型的方法。参考 inspectdb 文档 获取更多信息

补充:
1. 通用字段属性

选项说明
null数据库中对应的字段是否允许为NULL,默认为False
blank后台模型管理验证数据时,是否允许为NULL,默认为False
choices设定字段的选项,各元组中的第一个值是设置在模型上的值,第二值是人类可读的值
db_column字段对应到数据库表中的列名,未指定时直接使用字段的名称
db_index设置为True时将在该字段创建索引
db_tablespace为有索引的字段设置使用的表空间,默认为DEFAULT_INDEX_TABLESPACE
default字段的默认值
editable字段在后台模型管理或ModelForm中是否显示,默认为True
error_messages设定字段抛出异常时的默认消息的字典,其中的键包括nullblankinvalidinvalid_choiceuniqueunique_for_date
help_text表单小组件旁边显示的额外的帮助文本。
primary_key将字段指定为模型的主键,未指定时会自动添加AutoField用于主键,只读。
unique设置为True时,表中字段的值必须是唯一的
verbose_name字段在后台模型管理显示的名称,未指定时使用字段的名称

2. ForeignKey属性

  1. limit_choices_to:值是一个Q对象或返回一个Q对象,用于限制后台显示哪些对象。
  2. related_name:用于获取关联对象的关联管理器对象(反向查询),如果不允许反向,该属性应该被设置为'+',或者以'+'结尾。
  3. to_field:指定关联的字段,默认关联对象的主键字段。
  4. db_constraint:是否为外键创建约束,默认值为True
  5. on_delete:外键关联的对象被删除时对应的动作,可取的值包括django.db.models中定义的:
    • CASCADE:级联删除。
    • PROTECT:抛出ProtectedError异常,阻止删除引用的对象。
    • SET_NULL:把外键设置为null,当null属性被设置为True时才能这么做。
    • SET_DEFAULT:把外键设置为默认值,提供了默认值才能这么做。

3. ManyToManyField属性

  1. symmetrical:是否建立对称的多对多关系。
  2. through:指定维持多对多关系的中间表的Django模型。
  3. throughfields:定义了中间模型时可以指定建立多对多关系的字段。
  4. db_table:指定维持多对多关系的中间表的表名。

4. 模型元数据选项

选项说明
abstract设置为True时模型是抽象父类
app_label如果定义模型的应用不在INSTALLED_APPS中可以用该属性指定
db_table模型使用的数据表名称
db_tablespace模型使用的数据表空间
default_related_name关联对象回指这个模型时默认使用的名称,默认为<model_name>_set
get_latest_by模型中可排序字段的名称。
managed设置为True时,Django在迁移中创建数据表并在执行flush管理命令时把表移除
order_with_respect_to标记对象为可排序的
ordering对象的默认排序
permissions创建对象时写入权限表的额外权限
default_permissions默认为('add', 'change', 'delete')
unique_together设定组合在一起时必须独一无二的字段名
index_together设定一起建立索引的多个字段名
verbose_name为对象设定人类可读的名称
verbose_name_plural设定对象的复数名称

2 使用ORM完成模型的CRUD操作

2.1 基本的增删改查

        有了Django框架的ORM,我们可以直接使用面向对象的方式来实现对数据的CRUD(增删改查)操作。我们可以在PyCharm的终端中输入下面的命令进入到Django项目的交互式环境,然后尝试对模型的操作。

python manage.py shell

1. 新增

from polls.models import Subject

Subject.objects.create(name='H5前端开发', intro='前段比较热的学科', is_hot=True)

subject1 = Subject(name='Python全栈开发', intro='当下最热门的学科', is_hot=True)
subject1.save()
subject2 = Subject(name='全栈软件测试', intro='学习自动化测试的学科', is_hot=False)
subject2.save()
subject3 = Subject(name='JavaEE分布式开发', intro='基于Java语言的服务器应用开发', is_hot=True)

2. 删除

subject = Subject.objects.get(no=2)
subject.delete()

3. 更新

subject = Subject.objects.get(no=1)
subject.name = 'Python全栈+人工智能'
subject.save()

4. 查询

(1) 查询所有对象

Subject.objects.all()

(2) 过滤数据

# 查询名称为“Python全栈+人工智能”的学科
Subject.objects.filter(name='Python全栈+人工智能')

# 查询名称包含“全栈”的学科(模糊查询)
Subject.objects.filter(name__contains='全栈')
Subject.objects.filter(name__startswith='全栈')
Subject.objects.filter(name__endswith='全栈')

# 查询所有热门学科
Subject.objects.filter(is_hot=True)

# 查询编号大于3小于10的学科
Subject.objects.filter(no__gt=3).filter(no__lt=10)
Subject.objects.filter(no__gt=3, no__lt=10)

# 查询编号在3到7之间的学科
Subject.objects.filter(no__gte=3, no__lte=7)
Subject.objects.filter(no__range=(3, 7))

(3) 查询单个对象

# 查询主键为1的学科
Subject.objects.get(pk=1)
Subject.objects.get(no=1)
Subject.objects.filter(no=1).first()
Subject.objects.filter(no=1).last()

(4) 排序

# 查询所有学科按编号升序排列
Subject.objects.order_by('no')
# 查询所有部门按部门编号降序排列
Subject.objects.order_by('-no')

(5) 切片

# 按编号从小到大查询前3个学科
Subject.objects.order_by('no')[:3]

(6) 计数

# 查询一共有多少个学科
Subject.objects.count()

(7) 高级查询

# 查询编号为1的学科的老师
Teacher.objects.filter(sno__no=1)
Subject.objects.get(pk=1).teacher_set.all() 

# 查询学科名称有“全栈”二字的学科的老师
Teacher.objects.filter(sno__name__contains='全栈') 

        上面的 objects 是一个特殊的属性,通过它来查询数据库,它是模型的一个 Manager。在 filter() 方法中还有一些比较神奇的双下划线辅助我们进一步过滤结果,详细了解,请阅读官方文档————执行查询

温馨提示:

  • 说明1:由于老师与学科之间存在多对一外键关联,所以能通过学科反向查询到该学科的老师(从一对多关系中“一”的一方查询“多”的一方),反向查询属性默认的名字是类名小写_set(如上面例子中的teacher_set),当然也可以在创建模型时通过ForeingKey的related_name属性指定反向查询属性的名字。如果不希望执行反向查询可以将related_name属性设置为’+‘或者以’+'开头的字符串。
  • 说明2:ORM查询多个对象时会返回QuerySet对象,QuerySet使用了惰性查询,即在创建QuerySet对象的过程中不涉及任何数据库活动,等真正用到对象时(对QuerySet求值)才向数据库发送SQL语句并获取对应的结果,这一点在实际开发中需要引起注意!
  • 说明3:如果希望更新多条数据,不用先逐一获取模型对象再修改对象属性,可以直接使用QuerySet对象的update()方法一次性更新多条数据。

参考

  • Django 使用原生的 SQL 语句操作 MySQL 数据库:https://www.imooc.com/wiki/djangolesson/nativesql.html
  • 深入模型:https://gitee.com/zengyujin/Python-100-Days/blob/master/Day41-55/42.深入模型.md
  • Django入门指南-第5章:模型设计:https://www.bookstack.cn/read/django-beginners-guide-zh/Fundamentals-2.md
  • Django v4.0 中文文档 模型:https://www.bookstack.cn/read/Django-4.0-zh/94d959954f3d0daa.md

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/347942.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里云部署SpringBoot项目

目录 步骤1&#xff1a;购买服务器(新用户免费试用一个月) 步骤2&#xff1a;查看服务器相关信息 ​编辑 步骤3&#xff1a;设置安全组 步骤4&#xff1a;远程连接 步骤5&#xff1a;使用FinalShell连接阿里云服务器 步骤6&#xff1a;阿里云服务器上安装JDK ​编辑 步骤7…

Inception Transformer

paper链接: https://arxiv.org/abs/2205.12956v2 code链接: https://github.com/sail-sg/iFormer Inception Transformer一、引言二、实现细节三、实验一、分类二、检测三、分割四、消融实验一、引言 最近的研究表明&#xff0c;Transformer具有很强的建立远程依赖关系的能力…

vAPI:一个自托管的OWASP Top 10漏洞API靶场

关于vAPI vAPI是一款针对OWASP Top 10漏洞的练习靶场&#xff0c;vAPI项目是一个故意引入了多种漏洞的可编程接口API&#xff0c;广大研究人员可以利用vAPI来研究和练习OWASP Top 10漏洞。 工具要求 PHP MySQL PostMan Mitmproxy 工具安装 Docker安装 docker-compose up -d…

Jira和Confluence Server版终止支持倒计时365天,企业应对策略汇总

本文对Atlassian最新的Server版政策进行了解读&#xff0c;并给出应对方案&#xff1b;同时我们也将国内热门的替代工具与jira进行了比较细致的对比&#xff0c;以及介绍替换的优惠政策等。今天是2023年2月15日&#xff0c;距离 Atlassian 旗下 Jira、Confluence 等系列产品中国…

互联网的路由选择协议

互联网的路由选择协议 文章目录互联网的路由选择协议路由选择协议的几个概念分层次路由选择协议内部网关协议RIP协议距离向量算法RIP协议的报文格式内部网关协议OSPFOSPF的报文格式✨OSPF的特点外部网关协议BGPBGP的报文格式参考本篇主要讨论的是路由表中的路由是如何得出来的。…

如何获取 openai ChatGPT的key?(图文教学)

我直接对他进行询问 Q&#xff1a;获取chatptp的key A&#xff1a;对不起&#xff0c;作为ChatGPT&#xff0c;我不具有API密钥或访问凭据。我只是一个已经被训练好的自然语言处理模型&#xff0c;通过输入文本来生成回复。您可以在OpenAI的网站上了解有关他们的API和访问凭据…

Gif动态图片怎样在线生成?一招快速完成gif在线制作

Gif表情包作为日常聊天中必备的气氛调和剂&#xff0c;不仅能够更好的表达出自己的内心情绪&#xff0c;还能够缓解聊天的尴尬。那么&#xff0c;要怎么制作gif表情包呢&#xff1f;下面&#xff0c;介绍两个简单的方法&#xff0c;轻松一键就能在线完成gif制作&#xff08;htt…

Linux安装elasticsearch-head

elasticsearch-head 是一款专门针对于 elasticsearch 的客户端工具&#xff0c;用来展示数据。 elasticsearch-head 是基于 JavaScript 语言编写的&#xff0c;可以使用 Nodejs 下的包管理器 npm 部署。 1 安装Nodejs nodejs下载地址&#xff1a; https://nodejs.org/en/dow…

记一次OOM

1,问题描述&#xff1a; 新上了一版代码之后&#xff0c;上游服务请求我们服务失败&#xff0c;报错&#xff1a;“服务不可用”&#xff0c;发现注册中心上服务掉线&#xff0c;查询日志&#xff1a;发现oom&#xff1a;Java heap space,GC overhead limit exceeded。 容易…

国产电容式触控IC的工作原理及应用

国产电容式触控IC采用CMOS工艺&#xff0c;内建稳压和驱动电路&#xff0c;具有高可靠性、高灵敏度、超低功耗、强稳定性、抗干扰能力强、宽工作电压等方面优点&#xff0c;专为取代光感和传统按键开发而设计。 电容式触控芯片 - CT8225是一款使用电容感应式原理设计的触摸芯片…

Linux_基本指令

新的专栏Linux入门来啦&#xff01;欢迎各位大佬补充指正&#xff01;&#xff01; Linux_基本指令导入文件绝对路径与相对路径隐藏的文件指令ls查看stat查看文件属性cd进入路径mkdir创建目录touch创建文件rm删除man查询手册cp复制mv移动cat查看文件morelessheadtail时间相关的…

redis分布式锁的演变过程

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一、直接添加Redis缓存二、使用setnx执行抢锁过程三、setnx获取锁+设置过期时间四、引入UUID解决误删锁问题五、引入Lua脚本来做删除六、对递归部分优化进行自旋七、添加自旋次数八、改为重入锁,使…

Grafana loki部署及使用及问题处理方法(超详细)

一、下载软件 因为我是本地测试&#xff0c;所以用的windows版本的包&#xff0c;loki服务window版本的安装包下载地址&#xff1a;下载地址&#xff0c;选择 promtail-windows版本的安装包下载地址&#xff1a;下载地址 Grafana服务的下载地址&#xff1a;下载地址 二、配置…

月薪过万的那些人,大部分都是做什么工作的?

三百六十行&#xff0c;行行出状元。不管是什么行业&#xff0c;月薪过万都是有的。只不过有些行业就是比较容易出现月薪过万&#xff0c;换句话说&#xff0c;就是这个行业内出现月薪过万的人数比较多。先说结论&#xff0c;综合来看月薪过万的这部分90后&#xff0c;大部分集…

JavaScript语法学习--《JavaScript编程全解》

《JavaScript编程全解》 JavaScript琐碎基础 0.前言 1.RN: react native是Facebook于2015年4月开源的跨平台移动应用开发框架&#xff0c;是Facebook早先开源的JS框架 React 在原生移动应用平台的衍生产物&#xff0c;支持iOS和安卓两大平台。 2.ts与js js&#xff1a;是弱…

[CentOS] Dell塔式服务器安装CentOS7

主要基于 UEFI GPT方式引导&#xff0c;LegacyMBR的方式这里不做讨论 目录基础信息BIOS设置U盘制作启动盘启动安装注意事项基础信息 CentOS7.5UltraISO 9.3.x机型&#xff1a;DELL OPTIPLEX 7080机型&#xff1a; DELL OPTIPLEX 5090机型&#xff1a; DELL OPTIPLEX 300U盘&a…

ChatGPT 未来会造成大量职业的裁员和失业吗?

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;一个有趣的事情&#xff0c;一个有趣的事情&#xff0c;今天让我们一起来看看吧&#xff01; 1、chatGpt来自那个国家&#xff1f; ChatGPT是一种聊天机器人技术&#xff0c;它来自美国&#xff0c;由OpenAI公司开发。…

HR管理系统的五大选择特点

市面上的HR管理系统那么多&#xff0c;难免选的眼花缭乱。我们的建议是&#xff0c;就根据你们自己的需求来&#xff0c;满足自身需求的&#xff0c;才是最好的。当然价格页得考虑。如果HRMS与你的组织需求不一致&#xff0c;则会妨碍有效的HR管理。跟着下面的步骤去选一款HR产…

第四章 - 基础查询语句(select,distinct,limit)

基础查询语句&#xff0c;select&#xff0c;distinct&#xff0c;limit查询单列数据查询多列数据查询所有数据去重查询&#xff08;distinct&#xff09;限制查询结果&#xff08;limit&#xff09;查询单列数据 在列名和函数没有冲突的时候可以不用加前后的比如有时候时间的…

微信小程序|基于小程序+C#制作一个超酷的个人简历

你还在用以前的方式投简历吗?趁着金三银四来临之际,跟随此文使用小程序制作一个便携超酷的个人简历,高调炫技,愉快的收offer吧! 一、小程序