目 录
前言:以下操作的数据库表模型如下(app01下的models.py):
from django.db import models # Create your models here. # 自定义char类型 class MyCharField(models.Field): def __init__(self,max_length,*args,**kwargs): self.max_length = max_length super().__init__(max_length=max_length,*args,**kwargs) def db_type(self, connection): return 'char(%s)'%self.max_length ''' 建表时,要注意先将主表建好,在建立表关系 ''' class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8, decimal_places=2) publish_date = models.DateField() maichu = models.IntegerField(default=1000) kucun = models.IntegerField(default=1000) # 书籍和出版社是一对多的关系,外键建在多的一方 publish = models.ForeignKey(to='Publish') # 书籍和作者是多对多的关系,需要第三张表 authors = models.ManyToManyField(to='Author') def __str__(self): return self.title class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=255) def __str__(self): return self.name class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() hobby = MyCharField(max_length=32,default='read') # 作者和作者详情是一对一的关系,外键建立在查询频率高的一方 author_detail = models.OneToOneField(to='AuthorDetail') def __str__(self): return self.name class AuthorDetail(models.Model): phone = models.BigIntegerField() addr = models.CharField(max_length=64) def __str__(self): return self.addr
一、聚合查询
聚合函数:在已经搭建好测试环境的tesy.py中导入聚合函数
from django.db.models import Max,Min,Sum,Count,Avg
""" 聚合查询 关键字:aggregate """ from django.db.models import Max,Min,Count,Sum,Avg # 统计所有书平均价格 # res = models.Book.objects.all().aggregate(Avg('price')) # res1 = models.Book.objects.all().aggregate(Max('price')) # res2 = models.Book.objects.all().aggregate(Min('price')) # res3 = models.Book.objects.all().aggregate(Sum('price')) # res4 = models.Book.objects.all().aggregate(Count('title')) # res5 = models.Book.objects.all().aggregate(Avg('price'),Max('price'),Min('price'),Sum('price'),Count('title')) # print(res5)
二、分组查询
""" 分组查询 关键字:annotate """ # 1.统计每一本书的作者个数 # res = models.Book.objects.annotate(author_num = Count('authors')).values('author_num') # print(res) # 2.统计出每个出版社卖的最便宜的书的价格 # res = models.Publish.objects.annotate(price_min=Min('book__price')).values('price_min') # print(res) # 3.统计不止一个作者的图书 """ 1.统计每本书对应的作者个数 2.基于上面的结果 筛选出作者个数大于1 的 """ # res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('author_num') # print(res) # 4.查询各个作者出的书的总价格 # res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('sum_price') # print(res)
三、F、Q查询
F查询
在上面所有的例子中,我们构造的过滤器都只是将字段值与某个我们自己设定的常量做比较。如果我们要对两个字段的值做比较,那该怎么做呢?
Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。
""" F与Q查询 我们之前在查询数据库的时候条件都是我们自己手写的 但是现在出现了条件是从数据库里面获取的 """ # F from django.db.models import F,Q # 1.查询出卖出数大于库存数的书籍 # res = models.Book.objects.filter(maichu__gt=F('kucun')) # print(res) # 2.将所有的书的价格 全部提高100块 # models.Book.objects.update(price=F('price') + 100) # 3.了解 尝试着将所有的书的名字后面都加上 爆款
F可以帮我们取到表中某个字段对应的值来当作我的筛选条件,而不是我认为自定义常量的条件了,实现了动态比较的效果
Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。
基于此可以对表中的数值类型进行数学运算,如:将所有书的价格提高100元钱
Q查询
filter() 等方法中逗号隔开的条件是与的关系。 如果你需要执行更复杂的查询(例如OR语句),你可以使用Q对象。
对条件包裹一层Q时候,filter即可支持交叉并的比较符(即‘与’ ‘或’ ‘非’ 等关系运算)
""" Q查询 """ # 1.查询书籍名称是python入门或者价格是544.44的书 # res = models.Book.objects.filter(title='python入门',price=544.44) # res = models.Book.objects.filter(Q(title='python入门'),Q(price=544.44)) # 逗号就是and # res = models.Book.objects.filter(Q(title='python入门')|Q(kucun=666)) # 用来Q之后 就能够支持|表示或 # res = models.Book.objects.filter(~Q(title='python入门')|Q(kucun=666)) # esc下面那个键 波浪号 表示非 # print(res) # Q查询进阶用法 用Q产生对象 然后再使用 # q = Q() # q.connector = 'or' # q.children.append(('title__icontains','p')) # # q.children.append(('kucun',666)) # res = models.Book.objects.filter(q) # print(res) """ 字符串的左边 跟你的变量名条件书写一模一样 """
我们可以组合& 和| 操作符以及使用括号进行分组来编写任意复杂的Q 对象。
同时,Q 对象可以使用~ 操作符取反,这允许组合正常的查询和取反(NOT) 查询。
示例:
查询 库存数是100 并且 卖出数不是0 的产品
models.Product.objects.filter(Q(kucun=100)&~Q(maichu=0))
四、自定义char字段
# 自定义char类型字段 class MyCharField(models.Field): def __init__(self,max_length,*args,**kwargs): self.max_length = max_length super().__init__(max_length=max_length,*args,**kwargs) def db_type(self, connection): return 'char(%s)'%self.max_length
运用自定义的char定义模型表的‘info’字段:
class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) publish_date = models.DateField(auto_now_add=True) info = MyCharField(max_length=32,null=True) maichu = models.IntegerField(default=1000) kucun = models.IntegerField(default=1000) # 书籍与出版社 是一对多关系 publish = models.ForeignKey(to='Publish') # 书籍与作者 是多对多 authors = models.ManyToManyField(to='Author') """ authors虚拟字段 1.告诉orm自动帮你创建第三张关系表 2.orm查询的时候 能够帮助你更加方便的查询 """
五、查询优化(*****面试重点)
查询优化(面试比较喜欢问的)
only与defer
select_related和prefetch_related
代码示例:
# 惰性查询 # res = models.Book.objects.all() # res = models.Book.objects.values('title') # res = models.Book.objects.only('title') # for r in res: # # print(r.title) # print(r.price) """ only会将括号内的字段对应的值 直接封装到返回给你的对象中 点该字段 不需要再走数据库 一旦你点了不是括号内的字段 就会频繁的去走数据库查询 """ # res = models.Book.objects.defer('title') # defer和only互为反关系 # for r in res: # print(r.title) """ defer会将括号内的字段排除之外将其他字段对应的值 直接封装到返回给你的对象中 点该其他字段 不需要再走数据库 一旦你点了括号内的字段 就会频繁的去走数据库查询 """ # res = models.Book.objects.select_related('publish') # res1 = models.Author.objects.select_related('author_detail') # # res = models.Book.objects.all() # for r in res1: # print(r.author_detail) # print(r.author_detail.phone) # print(r.author_detail.addr) """ select_related 会自动帮你做连表操作 然后将连表之后的数据全部查询出来封装给对象 select_related括号内只能放外键字段 并且多对多字段不能放 如果括号内外键字段所关联的表中还有外键字段 还可以继续连表 select_related(外键字段__外键字段__外键字段...) """ # prefetch_related res = models.Book.objects.prefetch_related('publish') # print(res) for r in res: print(r.publish.name) """ prefetch_related 看似连表操作 其实是类似于子查询 prefetch_related括号内只能放外键字段 并且多对多字段不能放 如果括号内外键字段所关联的表中还有外键字段 还可以继续连表 select_related(外键字段__外键字段__外键字段...) """ """ 第一个 内部自动连表 消耗的资源就在连表上 但是走数据库的次数较少 第二个 内部不做连表 消耗的资源就在查询次数上 但是给用户的感觉跟连表操作一样 """
六、Django ORM中的事务操作
数据库中事务的4大特性,ACID:原子性、一致性、隔离性、持久性。
事务的提交:commit
事务的回滚:rollback
# django中如何开启事务 from django.db import transaction with transaction.atomic(): # 在该代码块中所写的orm语句 同属于一个事务 # 缩进出来之后自动结束
七、案例--图书管理系统
开启一个Django项目,需要注意事项:
1、首先在Navacat中建好数据库并在应用文件夹下的init.py文件中导入pymysql,在应用models.py 下建好模型表;
2、然后在settings.py文件下进行静态文件配置,在跟目录下创建static文件夹,放置bootstraip文件;
3、在templates文件夹中创建HTML文件时,注意配置{% load static%} link script 等配置代码;
4、POST提交请求时,注意要在settings.py文件中注释CRSF...中间件
代码如下:
app01文件夹:
import pymysql pymysql.install_as_MySQLdb()
from django.db import models # Create your models here. """ 你在写orm语句的时候 跟你写sql语句一样 不要想着一次性写完 写一点查一点看一点 """ # 自定义char类型字段 class MyCharField(models.Field): def __init__(self,max_length,*args,**kwargs): self.max_length = max_length super().__init__(max_length=max_length,*args,**kwargs) def db_type(self, connection): return 'char(%s)'%self.max_length class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) publish_date = models.DateField(auto_now_add=True) # info = MyCharField(max_length=32,null=True) # # maichu = models.IntegerField(default=1000) # kucun = models.IntegerField(default=1000) # 书籍与出版社 是一对多关系 publish = models.ForeignKey(to='Publish') # 书籍与作者 是多对多 authors = models.ManyToManyField(to='Author') """ authors虚拟字段 1.告诉orm自动帮你创建第三张关系表 2.orm查询的时候 能够帮助你更加方便的查询 """ def __str__(self): return self.title class Publish(models.Model): name = models.CharField(max_length=32) addr = models.CharField(max_length=64) def __str__(self): return self.name """return返回的数据必须是字符串类型""" class Author(models.Model): name = models.CharField(max_length=32) age = models.IntegerField() # author_detail = models.ForeignKey(unique=True,to='AuthorDetail') author_detail = models.OneToOneField(to='AuthorDetail') def __str__(self): return self.name class AuthorDetail(models.Model): phone = models.BigIntegerField() addr = models.CharField(max_length=64) def __str__(self): return self.addr
from django.shortcuts import render,HttpResponse,redirect,reverse from app01 import models # Create your views here. def home(request): return render(request,'home.html') def book_list(request): # 将网站所有的书籍查询出来 book_queryset = models.Book.objects.all() return render(request,'book_list.html',locals()) def add_book(request): if request.method == 'POST': title = request.POST.get('title') price = request.POST.get('price') publish_date = request.POST.get('publish_date') publish_id = request.POST.get('publish') authors_list = request.POST.getlist('authors') # 操作书籍表 book_obj = models.Book.objects.create(title=title,price=price,publish_date=publish_date,publish_id=publish_id) # 操作书籍与作者的关系表 book_obj.authors.add(*authors_list) # 跳转到展示页面 _url = reverse('list') return redirect(_url) # 把出版社和作者全部查询出来 publish_queryset = models.Publish.objects.all() authors_queryset = models.Author.objects.all() return render(request,'add_book.html',locals()) def edit_book(request,edit_id): # 获取到用户想要编辑的数据的主键值 edit_obj = models.Book.objects.filter(pk=edit_id).first() if request.method == 'POST': title = request.POST.get('title') price = request.POST.get('price') publish_date = request.POST.get('publish_date') publish_id = request.POST.get('publish') authors_list = request.POST.getlist('authors') models.Book.objects.filter(pk=edit_id).update(title=title,price=price,publish_date=publish_date,publish_id=publish_id) edit_obj.authors.set(authors_list) # 跳转到书籍的展示页面 _url = reverse('list') return redirect(_url) # 将用户想要编辑的数据对象 展示给用户看 # 把出版社和作者全部查询出来 publish_queryset = models.Publish.objects.all() authors_queryset = models.Author.objects.all() return render(request,'edit_book.html',locals()) def delete_book(request,delete_id): models.Book.objects.filter(pk=delete_id).delete() return redirect(reverse('list'))
BMS文件夹:
""" Django settings for BMS project. Generated by 'django-admin startproject' using Django 1.11.11. For more information on this file, see https://docs.djangoproject.com/en/1.11/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.11/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = ')9mson%8(483jjy+sof)83k$q%6!$r-9pwwjx+(dmestlf_-s4' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', ] MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', # 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] ROOT_URLCONF = 'BMS.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'BMS.wsgi.application' # Database # https://docs.djangoproject.com/en/1.11/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'day61', 'USER': 'root', 'PASSWORD': "root", 'HOST': '127.0.0.1', 'PORT': 3306, 'CHARSET': 'utf8' } } # Password validation # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] # Internationalization # https://docs.djangoproject.com/en/1.11/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.11/howto/static-files/ STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR,'static') ]
"""BMS URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/', admin.site.urls), # 图书管理系统首页 url(r'^$', views.home), # 图书展示页面 url(r'^book_list/', views.book_list,name='list'), # 图书的添加页面 url(r'^add_book/',views.add_book,name='add'), # 图书的编辑页面 url(r'^edit_book/(d+)/',views.edit_book,name='edit'), # 图书的删除页面 url(r'^delete_book/(d+)/',views.delete_book,name='delete') ]
static文件夹:
存放bootstraip文件
templates文件夹:
{% extends 'home.html' %} {% block content %} <h2 class="text-center">添加页面</h2> <form action="" method="post"> <p>title:<input type="text" name="title" class="form-control"></p> <p>price:<input type="text" name="price" class="form-control"></p> <p>publish_date:<input type="date" name="publish_date" class="form-control"></p> <p>publish: {# 将当前网站所有的出版社 展示给用户看#} <select name="publish" id="" class="form-control"> {% for publish_obj in publish_queryset %} <option value="{{ publish_obj.pk }}">{{ publish_obj.name }}</option> {% endfor %} </select> </p> <p>authors: {# 将当前网站所有的作者 展示给用户看#} <select name="authors" id="" class="form-control" multiple> {% for author_obj in authors_queryset %} <option value="{{ author_obj.pk }}">{{ author_obj.name }}</option> {% endfor %} </select> </p> <input type="submit" class="btn btn-primary pull-right"> </form> {% endblock %}
{% extends 'home.html' %} {% block content %} <h2 class="text-center">图书列表</h2> <a href="{% url 'add' %}" class="btn btn-success">添加书籍</a> <table class="table table-bordered table-striped table-hover"> <thead> <tr> <th>编号</th> <th>书名</th> <th>价格</th> <th>出版日期</th> <th>出版社</th> <th>作者</th> <th>操作</th> </tr> </thead> <tbody> {% for book_obj in book_queryset %} <tr> <td>{{ forloop.counter }}</td> <td>{{ book_obj.title }}</td> <td>{{ book_obj.price }}</td> <td>{{ book_obj.publish_date|date:'Y-m-d' }}</td> <td>{{ book_obj.publish.name }}</td> <td> {% for author_obj in book_obj.authors.all %} {% if forloop.last %} {{ author_obj.name }} {% else %} {{ author_obj.name }}, {% endif %} {% endfor %} </td> <td> <a href="{% url 'edit' book_obj.pk %}" class="btn btn-primary btn-sm">编辑</a> <a href="{% url 'delete' book_obj.pk %}" class="btn btn-danger btn-sm">删除</a> </td> </tr> {% endfor %} </tbody> </table> {% endblock %}
{% extends 'home.html' %} {% block content %} <h2 class="text-center">编辑页面</h2> <form action="" method="post"> <p>title:<input type="text" name="title" class="form-control" value="{{ edit_obj.title }}"></p> <p>price:<input type="text" name="price" class="form-control" value="{{ edit_obj.price }}"></p> <p>publish_date:<input type="date" name="publish_date" class="form-control" value="{{ edit_obj.publish_date|date:'Y-m-d' }}"></p> <p>publish: {# 将当前网站所有的出版社 展示给用户看#} <select name="publish" id="" class="form-control"> {% for publish_obj in publish_queryset %} {% if edit_obj.publish == publish_obj %} <option value="{{ publish_obj.pk }}" selected>{{ publish_obj.name }}</option> {% else %} <option value="{{ publish_obj.pk }}">{{ publish_obj.name }}</option> {% endif %} {% endfor %} </select> </p> <p>authors: {# 将当前网站所有的作者 展示给用户看#} <select name="authors" id="" class="form-control" multiple> {% for author_obj in authors_queryset %} {% if author_obj in edit_obj.authors.all %} <option value="{{ author_obj.pk }}" selected>{{ author_obj.name }}</option> {% else %} <option value="{{ author_obj.pk }}">{{ author_obj.name }}</option> {% endif %} {% endfor %} </select> </p> <input type="submit" class="btn btn-warning pull-right"> </form> {% endblock %}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> {% load static %} <link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}"> <script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script> <style> table { margin-top: 5px; } </style> </head> <body> <nav class="navbar navbar-inverse"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header"> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand" href="#">图书管理系统</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">书籍 <span class="sr-only">(current)</span></a></li> <li><a href="#">作者</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">更多 <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> <li role="separator" class="divider"></li> <li><a href="#">One more separated link</a></li> </ul> </li> </ul> <form class="navbar-form navbar-left"> <div class="form-group"> <input type="text" class="form-control" placeholder="Search"> </div> <button type="submit" class="btn btn-default">搜索</button> </form> <ul class="nav navbar-nav navbar-right"> <li><a href="#">Welcome!</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">更多操作 <span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="#">Action</a></li> <li><a href="#">Another action</a></li> <li><a href="#">Something else here</a></li> <li role="separator" class="divider"></li> <li><a href="#">Separated link</a></li> </ul> </li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <div class="container-fluid"> <div class="row"> <div class="col-md-2"> <div class="list-group"> <a href="/" class="list-group-item active"> 首页 </a> <a href="{% url 'list' %}" class="list-group-item">图书列表</a> <a href="#" class="list-group-item">出版社列表</a> <a href="#" class="list-group-item">作者列表</a> <a href="#" class="list-group-item">其他</a> </div> </div> <div class="col-md-10"> <div class="panel panel-primary"> <div class="panel-heading"> <h3 class="panel-title">图书管理系统 <span class="glyphicon glyphicon-book pull-right"></span></h3> </div> <div class="panel-body"> {% block content %} <div class="jumbotron"> <h1>欢迎来到最牛逼的图书管理系统</h1> <p>亚洲最大的线上...</p> <p><a class="btn btn-primary btn-lg" href="#" role="button">了解更多</a></p> </div> {% endblock %} </div> </div> </div> </div> </div> </body> </html>
ORM中常见字段类型
''' orm中常见字段 AutoField(primary_key=True) CharField(max_length=32) varchar(32) IntegerField() int BigIntegerField() long DateField() auto_now:每次修改数据的时候 都会更新该字段 auto_now_add:只在创建数据的时候 才会自动将创建时间添加 后续不会再自动修改了 DecimalField() BooleanField(Field) - 布尔值类型 该字段在存储数据的时候 你只需要传布尔值即可 对应到数据库中 会变成0/1 TextField(Field) - 文本类型 存大段文本 EmailField(CharField) varchar(...) FileField(Field) - 字符串,路径保存在数据库,文件上传到指定目录 - 参数: upload_to = "" 上传文件的保存路径 storage = None 存储组件,默认django.core.files.storage.FileSystemStorage DecimalField(Field) - 10进制小数 - 参数: max_digits,小数总长度 decimal_places,小数位长度 '''