ORM简介

  • MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动
  • ORM是“对象-关系-映射”的简称。

如果进行数据库迁移,不同数据库的sql语句是有差别的,而ORM是上层封装,只需按照指定的数据库引擎就可以翻译为相对应的sql语句,便于数据库迁移。但是它的效率不高。

不需要调用sqmysql,django的上层封装;它只能做到表这一层

sql表----->python的 类

字段------>类的属性

表记录---->python类对象

#sql中的表                                                      

 #创建表:
CREATE TABLE employee(
id INT PRIMARY KEY auto_increment ,
name VARCHAR (20),
gender BIT default 1,
birthday DATA ,
department VARCHAR (20),
salary DECIMAL (8,2) unsigned,
); #sql中的表纪录 #添加一条表纪录:
INSERT employee (name,gender,birthday,salary,department)
VALUES ("alex",1,"1985-12-12",8000,"保洁部"); #查询一条表纪录:
SELECT * FROM employee WHERE age=24; #更新一条表纪录:
UPDATE employee SET birthday="1989-10-24" WHERE id=1; #删除一条表纪录:
DELETE FROM employee WHERE name="alex" #python的类
class Employee(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=32)
gender=models.BooleanField()
birthday=models.DateField()
department=models.CharField(max_length=32)
salary=models.DecimalField(max_digits=8,decimal_places=2) #python的类对象
#添加一条表纪录:
emp=Employee(name="alex",gender=True,birthday="1985-12-12",epartment="保洁部")
emp.save()
#查询一条表纪录:
Employee.objects.filter(age=24)
#更新一条表纪录:
Employee.objects.filter(id=1).update(birthday="1989-10-24")
#删除一条表纪录:
Employee.objects.filter(name="alex").delete()

在mysql中:

mysql> create database orm;
Query OK, 1 row affected (0.06 sec) mysql> use orm
Database changed
mysql> show tables;
Empty set (0.17 sec) mysql>
mysql> show tables;
+----------------------------+
| Tables_in_orm |
+----------------------------+
| app01_book #我们自己添加的 |
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
11 rows in set (0.00 sec) mysql> desc app01_book;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(32) | NO | | NULL | |
| pub_date | date | NO | | NULL | |
| price | decimal(8,2) | NO | | NULL | |
| publish | varchar(32) | NO | | NULL | |
+----------+--------------+------+-----+---------+----------------+
5 rows in set (0.04 sec)

 文件为ORM 

类对应表,类对象对应表记录

创建名为book的app,在book下的models.py中创建模型:

django里边的File、Class、Field、QuerySet等分别对应mysql里边的库、表、字段、记录,也就是相当于excel里边的Excel、Sheet、Column、Line;它们之间是互相联系的。

from django.db import models

# Create your models here.

class Book(models.Model):
id=models.AutoField(primary_key=True) #自增、参数
title=models.CharField(max_length=32) #
state=models.BooleanField()
pub_date=models.DateField()
price=models.DecimalField(max_digits=8,decimal_places=2) #浮点数,最大位8,得有2位是小数 123456.78
publish=models.CharField(max_length=32)

每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR数据库字段的大小。还有一些适用于所有字段的通用参数。 这些参数在文档中有详细定义,这里我们只简单介绍一些最常用的:

更多字段:

<1> CharField
字符串字段, 用于较短的字符串.
CharField 要求必须有一个参数 maxlength, 用于从数据库层和Django校验层限制该字段所允许的最大字符数. <2> IntegerField
#用于保存一个整数. <3> FloatField
一个浮点数. 必须 提供两个参数: 参数 描述
max_digits 总位数(不包括小数点和符号)
decimal_places 小数位数
举例来说, 要保存最大值为 999 (小数点后保存2位),你要这样定义字段: models.FloatField(..., max_digits=5, decimal_places=2)
要保存最大值一百万(小数点后保存10位)的话,你要这样定义: models.FloatField(..., max_digits=19, decimal_places=10)
admin 用一个文本框(<input type="text">)表示该字段保存的数据. <4> AutoField
一个 IntegerField, 添加记录时它会自动增长. 你通常不需要直接使用这个字段;
自定义一个主键:my_id=models.AutoField(primary_key=True)
如果你不指定主键的话,系统会自动添加一个主键字段到你的 model. <5> BooleanField
A true/false field. admin 用 checkbox 来表示此类字段. <6> TextField
一个容量很大的文本字段.
admin 用一个 <textarea> (文本区域)表示该字段数据.(一个多行编辑框). <7> EmailField
一个带有检查Email合法性的 CharField,不接受 maxlength 参数. <8> DateField
一个日期字段. 共有下列额外的可选参数:
Argument 描述
auto_now 当对象被保存时,自动将该字段的值设置为当前时间.通常用于表示 "last-modified" 时间戳.
auto_now_add 当对象首次被创建时,自动将该字段的值设置为当前时间.通常用于表示对象创建时间.
(仅仅在admin中有意义...) <9> DateTimeField
一个日期时间字段. 类似 DateField 支持同样的附加选项. <10> ImageField
类似 FileField, 不过要校验上传对象是否是一个合法图片.#它有两个可选参数:height_field和width_field,
如果提供这两个参数,则图片将按提供的高度和宽度规格保存.
<11> FileField
一个文件上传字段.
要求一个必须有的参数: upload_to, 一个用于保存上载文件的本地文件系统路径. 这个路径必须包含 strftime #formatting,
该格式将被上载文件的 date/time
替换(so that uploaded files don't fill up the given directory).
admin 用一个<input type="file">部件表示该字段保存的数据(一个文件上传部件) . 注意:在一个 model 中使用 FileField 或 ImageField 需要以下步骤:
(1)在你的 settings 文件中, 定义一个完整路径给 MEDIA_ROOT 以便让 Django在此处保存上传文件.
(出于性能考虑,这些文件并不保存到数据库.) 定义MEDIA_URL 作为该目录的公共 URL. 要确保该目录对
WEB服务器用户帐号是可写的.
(2) 在你的 model 中添加 FileField 或 ImageField, 并确保定义了 upload_to 选项,以告诉 Django
使用 MEDIA_ROOT 的哪个子目录保存上传文件.你的数据库中要保存的只是文件的路径(相对于 MEDIA_ROOT).
出于习惯你一定很想使用 Django 提供的 get_<#fieldname>_url 函数.举例来说,如果你的 ImageField
叫作 mug_shot, 你就可以在模板中以 {{ object.#get_mug_shot_url }} 这样的方式得到图像的绝对路径. <12> URLField
用于保存 URL. 若 verify_exists 参数为 True (默认), 给定的 URL 会预先检查是否存在( 即URL是否被有效装入且
没有返回404响应).
admin 用一个 <input type="text"> 文本框表示该字段保存的数据(一个单行编辑框) <13> NullBooleanField
类似 BooleanField, 不过允许 NULL 作为其中一个选项. 推荐使用这个字段而不要用 BooleanField 加 null=True 选项
admin 用一个选择框 <select> (三个可选择的值: "Unknown", "Yes" 和 "No" ) 来表示这种字段数据. <14> SlugField
"Slug" 是一个报纸术语. slug 是某个东西的小小标记(短签), 只包含字母,数字,下划线和连字符.#它们通常用于URLs
若你使用 Django 开发版本,你可以指定 maxlength. 若 maxlength 未指定, Django 会使用默认长度: 50. #在
以前的 Django 版本,没有任何办法改变50 这个长度.
这暗示了 db_index=True.
它接受一个额外的参数: prepopulate_from, which is a list of fields from which to auto-#populate
the slug, via JavaScript,in the object's admin form: models.SlugField
(prepopulate_from=("pre_name", "name"))prepopulate_from 不接受 DateTimeFields. <13> XMLField
一个校验值是否为合法XML的 TextField,必须提供参数: schema_path, 它是一个用来校验文本的 RelaxNG schema #的文件系统路径. <14> FilePathField
可选项目为某个特定目录下的文件名. 支持三个特殊的参数, 其中第一个是必须提供的.
参数 描述
path 必需参数. 一个目录的绝对文件系统路径. FilePathField 据此得到可选项目.
Example: "/home/images".
match 可选参数. 一个正则表达式, 作为一个字符串, FilePathField 将使用它过滤文件名.
注意这个正则表达式只会应用到 base filename 而不是
路径全名. Example: "foo.*\.txt^", 将匹配文件 foo23.txt 却不匹配 bar.txt 或 foo23.gif.
recursive可选参数.要么 True 要么 False. 默认值是 False. 是否包括 path 下面的全部子目录.
这三个参数可以同时使用.
match 仅应用于 base filename, 而不是路径全名. 那么,这个例子:
FilePathField(path="/home/images", match="foo.*", recursive=True)
...会匹配 /home/images/foo.gif 而不匹配 /home/images/foo/bar.gif <15> IPAddressField
一个字符串形式的 IP 地址, (i.e. "24.124.1.30").
<16> CommaSeparatedIntegerField
用于存放逗号分隔的整数值. 类似 CharField, 必须要有maxlength参数. '''

更多参数:

(1)null

如果为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False.

(1)blank

如果为True,该字段允许不填。默认为False。
要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。
如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。 (2)default 字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用。 (3)primary_key 如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True,
Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,
否则没必要设置任何一个字段的primary_key=True。 (4)unique 如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的 (5)choices
由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,<br>而且这个选择框的选项就是choices 中的选项。

settings配置

若想将模型转为mysql数据库中的表,需要在settings中配置:

DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'bms',      # 要连接的数据库,连接前需要创建好
'USER':'root',       # 连接数据库的用户名
'PASSWORD':'',       # 连接数据库的密码
'HOST':'127.0.0.1', # 连接主机,默认本级
'PORT':3306     # 端口 默认3306
}
}

  注意1:NAME即数据库的名字,在mysql连接前该数据库必须已经创建,而上面的sqlite数据库下的db.sqlite3则是项目自动创建 USER和PASSWORD分别是数据库的用户名和密码。设置完后,再启动我们的Django项目前,我们需要激活我们的mysql。然后,启动项目,会报错:no module named MySQLdb 。这是因为django默认你导入的驱动是MySQLdb,可是MySQLdb 对于py3有很大问题,所以我们需要的驱动是PyMySQL 所以,我们只需要找到项目名文件下的__init__,在里面写入:

1 import pymysql
2 pymysql.install_as_MySQLdb()

最后通过两条数据库迁移命令即可在指定的数据库中创建表 :

1 python manage.py makemigrations
2 python manage.py migrate

注意2:确保配置文件中的INSTALLED_APPS中写入我们创建的app名称

注意3:如果报错如下:

django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None

MySQLclient目前只支持到python3.4,因此如果使用的更高版本的python,需要修改如下:

通过查找路径C:\Programs\Python\Python36-32\Lib\site-packages\Django-2.0-py3.6.egg\django\db\backends\mysql
这个路径里的文件把

if version < (1, 3, 3):
raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)

注释掉 就OK了。

注意4: 如果想打印orm转换过程中的sql,需要在settings中进行如下配置:

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'propagate': True,
'level':'DEBUG',
},
}
}  

单表操作之添加表记录(有两种方法)

增加

views

from django.shortcuts import render, HttpResponse

# Create your views here.
from app01.models import Book #把Book类导出来
def index(request):
#添加表结构
##############################添加
#方式一(直接实例化一个实例对象,book_obj为实例对象)
#book_obj = Book(id=1, title="python红宝书", price=100, pub_date="2012-10-08", publish="人民出版社")
#book_obj.save() #只有这样这条表记录才会生成。 #方式二:create返回值就是当前生成的对象记录;每个表下面都有一个object管理器,可以对其进行增删改查
book_obj = Book.objects.create(title="php", price=100, pub_date="2018-01-01", publish="北京大学出版社" )#id不能重,刚刚设置自增了
print(book_obj.title) #对象下面的title属性
print(book_obj.price)
print(book_obj.pub_date) return HttpResponse('OK')
(0.000) SELECT @@SQL_AUTO_IS_NULL; args=None
(0.000) SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; args=None
(0.000) INSERT INTO `app01_book` (`title`, `pub_date`, `price`, `publish`) VALUES ('php', '2018-01-01', '100.00', '北京大学出版社'); args=['php', '2018-01-01', '100.00', '北京大学出版社']
[27/May/2018 10:47:36] "GET /index/ HTTP/1.1" 200 2
php
100
2018-01-01

单表操作之查询API  表记录

查询API

<1> all():                  查询所有结果

<2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象

<3> get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个,
如果符合筛选条件的对象超过一个或者没有都会抛出错误。 <4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象 <5> order_by(*field): 对查询结果排序 <6> reverse(): 对查询结果反向排序 <8> count(): 返回数据库中匹配查询(QuerySet)的对象数量。 <9> first(): 返回第一条记录 <10> last(): 返回最后一条记录 <11> exists(): 如果QuerySet包含数据,就返回True,否则返回False <12> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
model的实例化对象,而是一个可迭代的字典序列
<13> values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 <14> distinct(): 从返回结果中剔除重复纪录

views

from django.shortcuts import render, HttpResponse

# Create your views here.
from app01.models import Book
def index(request):
#添加表结构
##############################添加
#方式一
#book_obj = Book(id=1, title="python红宝书", price=100, pub_date="2012-10-08", publish="人民出版社")
#book_obj.save() #方式二:create返回值就是当前生成的对象记录
# book_obj = Book.objects.create(title="php", price=100, pub_date="2018-01-01", publish="北京大学出版社" )
# print(book_obj.title)
# print(book_obj.price)
# print(book_obj.pub_date) ##############################查询表记录API####################
'''
1.要知道方法的返回值;2方法的调用值(谁能调用)
:param request:
:return:
'''
#(1)all方法,查出所有结果。返回值是一个queryset对象,支持序列对象。
#book_list = Book.objects.all()
#print(book_list) #[obj,obj1,obj2,,,] #直接打印类的对象是一个object的一个结果如下,你可以在类里边加一个def __str__(self)
            #<QuerySet [<Book: Book object (1)>,Book:Book object (2)>]>      #    return self.title #这时候它就会打印它的title属性了
#<QyertSet [<Book: python>, <Book: php>]> # for obj in book_list: #支持for循环
# print(obj.title, obj.price)
#print(book_list[1].title) #支持索引、切片。 #(2)first,last;调用者为queryset对象,返回值为models对象 (<class ‘app01.models.Book’>)
#book = Book.objects.all().first() #拿到第一个models模型对象
#book = Book.objects.all()[0] #跟上边是一个意思。 #(3)filter() 返回值queryset对象 对比下filter和all;filter是拿到筛选条件的结果,all是拿到所有的结果。
# book_list = Book.objects.filter(price=100) #[obj,obj1,obj2...]
# print(book_list) #<QuerySet [<Book: python红宝书>, <Book: php>]>
# book_obj = Book.objects.filter(price=100).first()
  #SQL---> SELECT `app01_book`.`id`, `app01_book`.`title`, `app01_book`.`pub_date`, `app01_book`.`price`, `app01_book`.`publish` FROM `app01_book` WHERE `app01_book`.`price` = 100 LIMIT 21;
# ret = Book.objects.filter(title="go", price=200) #filter也可以加多个查询条件,这两个条件缺一不可。
# print(ret) #<QuerySet []>
#(4)get() 有且只有一个查询结果时才会拿出来,才会有意义,否则会报错 返回值:model对象
# book_obj = Book.objects.get(title="go")
# book_obj = Book.objects.get(title="price") #会报错哦
# print(book_obj.price)
SQL---> SELECT `app01_book`.`id`, `app01_book`.`title`, `app01_book`.`pub_date`, `app01_book`.`price`, `app01_book`.`publish` FROM `app01_book` WHERE `app01_book`.`title` = 'php';
#(5)exclude() 返回值:queryset对象
#ret = Book.objects.exclude(title="go") #除了title="go"的书籍全部给过滤出来。 排除条件过滤,filter是按照条件过滤
#print(ret) #<QuerySet [<Book: python红宝书>, <Book: php>]>
  SQL---> SELECT `app01_book`.`id`, `app01_book`.`title`, `app01_book`.`pub_date`, `app01_book`.`price`, `app01_book`.`publish` FROM `app01_book` WHERE NOT (`app01_book`.`title` = 'go') LIMIT 21; #(6)order_by() 调用者queryset对象; 返回值queryset对象
#ret = Book.objects.all().order_by("id") #从小到大
#ret = Book.objects.all().order_by("-id") #从大到小
   #ret = Book.objects.all().order_by("price")#按照价格大小排序
#ret = Book.objects.all().order_by("price", "id") #组合,当价格一样了就用id排序
#print(ret) #(7)count() 调用者queryset对象,返回值int
# ret = Book.objects.all().count() #SQL--->> SELECT COUNT(*) AS `__count` FROM `app01_book`;
# print(ret) #3 #(8)exist() 问是否存在
# ret = Book.objects.all().exists() 不要把所有数据都取出来,这样效率很慢。.exists下其实是取的是LIMIT 1(对应的sql语句)
# if ret:
# print("ok") #(9)values方法 调用者queryset对象,返回值queryset
# ret = Book.objects.all() #想拿到所有书籍的名称。
# for i in ret:
# print(i.tittle) #并不想拿对象,想拿对象里的某个字段
#ret = Book.objects.all().values("price", "title") #values()你想拿的字段。去掉all()也是一样的,.values就是.all()了;可以只加一个price的值。
'''
values的原理:
temp=[]
for obj in Book.objects.all()
temp.append({
"price"=obj.price
"title"=obj.title
})
return temp
'''
#print(ret) #列表里边放字典
#<QuerySet [{'price': Decimal('100.00')}, {'price': Decimal('100.00')}, {'price': Decimal('250.00')}]> #跟之前的QuerySet有区别,;列表里边放的不是一个个对象了而是个字典,把对象取出来的值作为键值对放在字典里;查询到几个对象就有几个字典。
#print(ret[0].get("price")) #100.00 #(10)values_list方法 调用者queryset对象,返回值queryset
#ret = Book.objects.all().values_list("price", "title")
#print(ret) #一个字典被换成元组了,列表里边放元组了,把字典的值去掉了,元组光有值。
#<QuerySet [(Decimal('100.00'), 'python红宝书'), (Decimal('100.00'), 'php'), (Decimal('250.00'),'go')]> '''values_list和values的区别:一个是字典、一个是元组;
values: <QuerySet [{'price': Decimal('100.00'), 'title': 'python红宝书'}, {'price': Decimal('100.00'), 'title': 'php'}, {'price': Decimal('250.00'), 'title': 'go'}]>
values_list <QuerySet [(Decimal('100.00'),'python红宝书'), (Decimal('100.00'), 'php'), (Decimal('250.00'), 'go')]>
'''
#(11) distinct(去重)
#ret = Book.objects.all().distinct() #这样写没有意义,把它们都distinct了,distinct一个有重复的字段才会有意义
#print(ret) #ret = Book.objects.all().values("price") # SQL --->  SELECT `app01_book`.`price` FROM `app01_book` LIMIT 21;
#print(ret) #<QuerySet [{'price': Decimal('100.00')}, {'price':Decimal('100.00')}, {'price': Decimal('250.00')}]>
  ret = Book.objects.all().values("price").distinct()  #SQL---> SELECT DISTINCT `app01_book`.`price` FROM `app01_book` LIMIT 21;
print(ret) #<QuerySet [{'price': Decimal('100.00')}, {'price': Decimal('250.00')}]>
return HttpResponse('OK')

单表查询之双下划线的模糊查询

###########################查询表记录之模糊查询######################
# ret = Book.objects.filter(price__gt=10, price__lt=200) #大于10小于200
# print(ret) #<QuerySet [<Book: python红宝书>, <Book: php>]> # ret = Book.objects.filter(title__startswith="py") #以py开头的
# print(ret) #<QuerySet [<Book: python红宝书>]> #ret = Book.objects.filter(title__contains="h") #只要包含h就可以给你查出来
# ret = Book.objects.filter(title__icontains="h") #不管大小写,只要包含就可以 #SQL---> SELECT `app01_book`.`id`, `app01_book`.`title`, `app01_book`.`pub_date`, `app01_book`.`price`, `app01_book`.`publish` FROM `app01_book` WHERE `app01_book`.`title` LIKE '%h%' LIMIT 21;
# print(ret) # ret = Book.objects.filter(price__in=[100, 200, 300])#在这个区间100-200-300的就会打印出 #WHERE `app01_book`.`price` IN (200, 100, 300) LIMIT 21;
# print(ret) #<QuerySet [<Book: python红宝书>, <Book: php>]> ret = Book.objects.filter(pub_date__year=2018, pub_date__month=5) #也可以不写后边的
print(ret)#<QuerySet [<Book: go>]> #SQL-->  WHERE (`app01_book`.`pub_date` BETWEEN '2018-01-01' AND '2018-12-31' AND EXTRACT(MONTH FROM `app01_book`.`pub_date`) = 5) LIMIT 21;
return HttpResponse('OK')

删除和修改

###########################删除记录和修改记录######################

    #delete:调用者为queryset对象  model对象
#ret = Book.objects.filter(price=250).delete() #没有返回值也可以删
#ret = Book.objects.filter(price=100).delete() #把两个都给删掉了
#print(ret) #(1, {'app01.Book': 1}) (2, {'app01.Book': 2}) #Book.objects.filter(price=100).first().delete() #只删除了一个

#update的调用者只能为queryset对象
ret = Book.objects.filter(title="php").update(title="python")
   return HttpResponse('OK')

删除方法就是 delete()。它运行时立即删除对象而不返回任何值。

你也可以一次性删除多个对象。每个 QuerySet 都有一个 delete() 方法,它一次性删除 QuerySet 中所有的对象。

在 Django 删除对象时,会模仿 SQL 约束 ON DELETE CASCADE 的行为,换句话说,删除一个对象时也会删除与它相关联的外键对象。

要注意的是: delete() 方法是 QuerySet 上的方法,但并不适用于 Manager 本身。这是一种保护机制,是为了避免意外地调用 Entry.objects.delete() 方法导致 所有的 记录被误删除。如果你确认要删除所有的对象,那么你必须显式地调用:

如果不想级联删除,可以设置为:

pubHouse = models.ForeignKey(to='Publisher', on_delete=models.SET_NULL, blank=True, null=True)

Python之路【第二十九篇】:django ORM模型层的更多相关文章

  1. Python之路(第二十九篇) 面向对象进阶:内置方法补充、异常处理

    一.__new__方法 __init__()是初始化方法,__new__()方法是构造方法,创建一个新的对象 实例化对象的时候,调用__init__()初始化之前,先调用了__new__()方法 __ ...

  2. Python之路(第二十八篇) 面向对象进阶:类的装饰器、元类

    一.类的装饰器 类作为一个对象,也可以被装饰. 例子 def wrap(obj): print("装饰器-----") obj.x = 1 obj.y = 3 obj.z = 5 ...

  3. Python之路(第二十五篇) 面向对象初级:反射、内置方法

    [TOC] 一.反射 反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省).这一概念的提出很快引发了计算机科学领域关于应用反射性的研究.它 ...

  4. Python之路(第二十四篇) 面向对象初级:多态、封装

    一.多态 多态 多态:一类事物有多种形态,同一种事物的多种形态,动物分为鸡类,猪类.狗类 例子 import abc class H2o(metaclass=abc.ABCMeta): ​ def _ ...

  5. Python之路(第二十六篇) 面向对象进阶:内置方法

    一.__getattribute__ object.__getattribute__(self, name) 无条件被调用,通过实例访问属性.如果class中定义了__getattr__(),则__g ...

  6. Python之路(第二十二篇) 面向对象初级:概念、类属性

    一.面向对象概念 1. "面向对象(OOP)"是什么? 简单点说,“面向对象”是一种编程范式,而编程范式是按照不同的编程特点总结出来的编程方式.俗话说,条条大路通罗马,也就说我们使 ...

  7. Python之路(第十九篇)hashlib模块

    一.hashlib模块 HASH Hash,一般翻译做“散列”,也有直接音译为”哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值 ...

  8. Python开发【第二十二篇】:Web框架之Django【进阶】

    Python开发[第二十二篇]:Web框架之Django[进阶]   猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...

  9. 【Python之路】第二十二篇--Django【基础篇】

    1 Django流程介绍 MTV模式       著名的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层:他们之间以一种插件似的,松耦合的方式连接在一起. 模型负责业 ...

随机推荐

  1. 使用grok exporter 做为log 与prometheus 的桥

    grok 是一个工具,可以用来解析非结构化的日志文件,可以使其结构化,同时方便查询,grok 被logstash 大量依赖 同时社区也提供了一个prometheus 的exporter 可以方便的进行 ...

  2. hive基础知识三

    1. 基本查询 注意 SQL 语言大小写不敏感 SQL 可以写在一行或者多行 关键字不能被缩写,也不能分行 各子句一般要分行写 使用缩进提高语句的可读性 1.1 全表和特定列查询 全表查询 selec ...

  3. request登录案例

    一.案例需求 1.编写login.html登录页面 username & password 两个输入框 2.使用Druid数据库连接池技术,操作mysql,day14数据库中user表 3.使 ...

  4. charles安装及使用

    一.下载安装charles 1.官方网址:https://www.charlesproxy.com/ 选择自己需要的macos/windows/linux下对应的最新版本安装即可 我的是mac,下载版 ...

  5. Sequelize 数据类型

    Sequelize.STRING // VARCHAR(255)Sequelize.STRING(1234) // VARCHAR(1234)Sequelize.STRING.BINARY // VA ...

  6. 你向 Mysql 数据库插入 100w 条数据用了多久?

    阅读本文大概需要 2 分钟. ▌目录 多线程插入(单表) 多线程插入(多表) 预处理 SQL 多值插入 SQL 事务( N 条提交一次) ▌多线程插入(单表) 问:为何对同一个表的插入多线程会比单线程 ...

  7. Redis(一) 数据结构与底层存储 & 事务 & 持久化 & lua

    参考文档:redis持久化:http://blog.csdn.net/freebird_lb/article/details/7778981 https://blog.csdn.net/jy69240 ...

  8. [Beta阶段]第十次Scrum Meeting

    Scrum Meeting博客目录 [Beta阶段]第十次Scrum Meeting 基本信息 名称 时间 地点 时长 第十次Scrum Meeting 19/05/16 大运村寝室6楼 30min ...

  9. JVM探究之 —— 类文件结构(脑图)

  10. 9个PNG透明图片免费下载网站推荐

    9个PNG透明图片免费下载网站推荐 酷站推荐 2017.08.06 13:47 png格式的图片因为去掉了的背景,方便使用在任何颜色的背景,所以对于从事设计师的朋友来说,经常会用到png透明图片.相信 ...