我叫什么啊 发表于 2020-2-18 20:18:39

学习总结

2020/2/18   今日学习总结:

021 内嵌函数和闭包:

1. global 关键字:将参数变成全局变量(可在函数中用,修改全局变量的值)

在函数内部只能访问全局变量,不可修改,否则系统会调用 屏蔽(Shadowing)来保护全局变量。屏蔽: 当在函数内要修改时,系统创建一个同名的局部变量,而不改变原本的全局变量。

2. Python支持函数的嵌套
>>> def fun1():
             print('fun1')

            #fun2 的定义和调用在fun1内,在fun1外找不到fun2
          def fun2():
                  print('fun2')
         
          fun2()

3. 闭包 :如果在一个内部函数里对外部作用域(但不是在全局作用域)的变量进行引用,内部函数就被任务是闭包。

【注】在python 中记住对象的名字,无论什么类型都是对象,所以可以将函数对象直接返回
>>> def funx(x):
          def funy(y):
                  return x*y
          return funy

注意调用格式!
① i = funx(8)
    i(6)
此时 i 的类型是函数,运算结果等于 8 * 6

② funx(8)(6)



>>> def fun1():
          x = 5
          def fun2():
                    x *= x
                  return x
          # 带括号返回的是函数,不带括号返回函数值??
          return fun2()

调用会出错,因为 fun2 的外部变量是fun1 的内部变量,x = 5 相当于fun2 的全局变量(非全局变量的外部变量)/ ???啥意思

[重点] 内部函数只能引用外部变量,不能修改

修改:
(1)Python3 以前:用 容器类型(用列表,因为列表不是存放在栈里面)
>>> def fun1():
           x =
           def fun2():
                  x *= x
                  return x
          return fun2()

(2)Python3 以后:
nonlocal 关键字:
>>> def fun1():
          x = 5
          def fun2():
                  #用nonlocal 关键字
                  nonlocal x
                  x *= x
                  return x
          return fun2()


022 lambda 表达式

1. 用 lambda 创建 匿名函数:

>>> lambda x : 2 * x + 1
<function <lambda> at 0x000001BA5697E430>
>>> g = lambda x : 2 * x + 1
>>> g(3)
7

>>> g = lambda x, y : x + y

2. ① 用lambda 使代码更精简② 不需要考虑命名的问题   ③简化代码的可读性

3.两个牛逼的BIF
(1)filter( ) : 过滤器
      有两个参数,第一个参数:函数 或 none, 如果第一个参数为函数时,第二个可迭代数据里的每个元素作为函数的参数作为计算,将返回true的值筛选出来并成一个列表;如果第一个参数为None,则将第二个参数中为true 的值筛选出来

【例1】
>>> list(filter(None,))       / 为什么用list( ) 方法?

【例2】过滤收集奇数
>>> def odd(x):
        return x % 2

>>> temp = range(10)
>>> show = filter(odd,temp)
>>> list(show)

用 lambda 可只用写一句话:
>>> list(filter((lambda x: x % 2),range(10)))

(2) map( ) :返回函数计算的值
>>> list(map(lambda x: x * 2, range(10)))



023 024 025递归 /阶乘/斐波那契数列/汉诺塔

递归:①有调用函数自身的行为 ②有正确的返回条件

【例】Fibonacci:
1123581321345589144
前者除后者 将接近于 0.618 : 1

n == 1: F(1) = 1
n == 2: F(2)= 1
n > 2: F(n) = F(n-1) + F(n-2)

递归:分治思想,把复杂大问题分解为若干个相对简单的小问题

我终于明白汉诺塔是干啥的了!!!啊打游戏去88

dxr001 发表于 2020-2-19 15:04:58

有帮助

我叫什么啊 发表于 2020-2-19 18:38:14

dxr001 发表于 2020-2-19 15:04
有帮助

那就好{:5_109:}

我叫什么啊 发表于 2020-2-19 19:13:23

map( ) 方法

我叫什么啊 发表于 2020-2-19 19:18:50

找100以内3的倍数:
①filter + lambda:
list(filter(lambda n : not(n%3), range(1, 100)))

②用列表推导式:
i for i in range(1,100) if x % 3 == 0

我叫什么啊 发表于 2020-2-25 20:52:30

本帖最后由 我叫什么啊 于 2020-3-4 17:09 编辑

026/027字典

>>> brand = ["李宁","耐克","阿迪达斯","鱼C"]
>>> slogen = ["一切皆有可能","Just do it","Impossible is nothing","让编程改变世界"]
>>> print('' , slogen)
让编程改变世界

index( ):返回索引值

字典:由多个 key 及其对应的 value 共同组成。(映射)
(字典用大括号,列表用中括号,元组用小括号或直接逗号隔开)
>>> dict1 = {"李宁":"一切皆有可能","耐克":"Just do it","阿迪达斯":"Impossible is nothing","鱼C":"让编程改变世界"}
>>> print("FishC口号:", dict1['鱼C'])
FishC口号: 让编程改变世界


>>> dict2 = {1:'one', 2:'two', 3:'three'}
>>> dict2
{1: 'one', 2: 'two', 3: 'three'}
>>> dict2
'three'

创建空的字典:
dict3 = {}

dict(mapping) : dict 只用一个参数,即映射类型的参数。是个工厂函数(类型),类:str( ), list( ), int( ), tuple( )
>>> dict3 = dict((('F',70),('i',105),('s',115),('h',104),('C',67)))
>>> dict3
{'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67}
>>> dict4 = dict(小甲鱼 = '123', 嗷嗷嗷 = '456' )
>>> dict4
{'小甲鱼': '123', '嗷嗷嗷': '456'}
>>> dict4['嗷嗷嗷'] = '789'
>>> dict4
{'小甲鱼': '123', '嗷嗷嗷': '789'}
>>> dict4['爱迪生'] = '1 + 99'
>>> dict4
{'小甲鱼': '123', '嗷嗷嗷': '789', '爱迪生': '1 + 99'}

字典中象的排列是随机的


fromkeys( ):dict.fromkeys(S[, v])   直接创建一个新的字典对象,不可用于修改原本的字典

>>> dict1.fromkeys((1,2,3))
{1: None, 2: None, 3: None}
>>> dict1.fromkeys((1,2,3), 'Test')
{1: 'Test', 2: 'Test', 3: 'Test'}
>>> dict1.fromkeys((1,2,3), ('Test1','Test2'))
{1: ('Test1', 'Test2'), 2: ('Test1', 'Test2'), 3: ('Test1', 'Test2')}
>>> dict1.fromkeys((1,3), ('Test1','Test2'))
{1: ('Test1', 'Test2'), 3: ('Test1', 'Test2')}
[注]第二个参数会整体赋值,且不能用于修改字典,只会重新创造字典

创建新字典:
>>> dict1 = dict1.fromkeys(range(3), 'Y')
>>> dict1
{0: 'Y', 1: 'Y', 2: 'Y'}

打印出所有的Key:
>>> for eachKey in dict1.keys():
        print(eachKey)

       
0
1
2

打印出所有的Value:
>>> for eachValue in dict1.values():
        print(eachValue)

       
Y
Y
Y

打印出所有的象:
>>> for eachItem in dict1.items():
        print(eachItem)

       
(0, 'Y')
(1, 'Y')
(2, 'Y')


用 get( ) 访问字典的象,如果没有(如越界了),会打印一个None
>>> print(dict1)
Traceback (most recent call last):
File "<pyshell#39>", line 1, in <module>
    print(dict1)
KeyError: 3
>>> dict1.get(3)
>>> print(dict1.get(3))
None

也可以自己设置当无数据时的输出,在有数据时则输出原本的数据:
>>> dict1.get(3,'无数据')
'无数据'
>>> dict1.get(1,'无数据')
'Y'

成员操作符: in和not in , 也可以用来查找字典中是否有所查询的Key
(字典用键Key查找,而不是值Value; 序列用值查找)
>>> 2 in dict1
True
>>> 3 in dict1
False
>>> dict3
{'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67}
>>> 'F' in dict3
True

clear() : 清空字典
dict1.clear()

以下方式不严谨,只是换了个空字典,但原字典还在
dict1 = {}


copy( ): 浅拷贝,只是对对象表层的拷贝(随后会继续深入讲解)
赋值不是浅拷贝,只是又给字典贴了标签
>>> dict1
{0: 'Y', 1: 'Y', 2: 'Y'}
>>> dict2 = dict1.copy()
>>> dict3 = dict1
>>> dict3
{0: 'Y', 1: 'Y', 2: 'Y'}
>>> dict2
{0: 'Y', 1: 'Y', 2: 'Y'}
>>> id(dict1)
2331611541248
>>> id(dict2)
2331611598656
>>> id(dict3)
2331611541248

dict1 与 dict3 要变一起变, dict2 不受另两个影响

pop( ) : 可弹出指定 Key 的 值 Value
popitem( ): 可认为是随机从字典里弹出一个象
setdefault( ): 查找指定 Key 的 Value ,若查不到指定 Key 就自动添加进去(也可以直接赋值)

>>> dict1.pop(2)
'Y'
>>> dict1
{0: 'Y', 1: 'Y'}
>>> dict1.popitem()
(1, 'Y')
>>> dict1
{0: 'Y'}
>>> dict1.setdefault('阿易','666')
'666'
>>> dict1
{0: 'Y', '阿易': '666'}


update( ) :用字典或一个映射关系去更新另一个字典
>>> dict1
{0: 'Y', '阿易': '666'}
>>> dict2
{0: 'Y', 1: 'Y', 2: 'Y'}
>>> dict2.update(dict1)
>>> dict2
{0: 'Y', 1: 'Y', 2: 'Y', '阿易': '666'}

我叫什么啊 发表于 2020-2-26 10:07:14

本帖最后由 我叫什么啊 于 2020-3-4 17:33 编辑

2020/2/26
028   集合

复习:字典 -->映射

集合中的元素都是唯一的,会直接过滤重复的数据; 集合是无序的,不支持索引。
创建时直接用 { }或 用 set( ) 工厂函数,用 set( ) 函数时可传入列表、元组、字符串。
>>> set1 = set()
>>> set1
{1, 2, 3, 4, 5}

在学集合以前,要去除列表中重复元素:

>>> num1 =
>>> temp = []
>>> for each in num1:
        if each not in temp:
                temp.append(each)

               
>>> temp


学习集合后:
>>> num1 = list(set(num1))
>>> num1



可用 for 来查找集合中的元素,或,用 in和 not in 来判断元素是否在集合中
>>> set1
{1, 2, 3, 4, 5}
>>> 2 in set1
True
>>> '2' in set1
False

add( ): 向集合里添加元素   remove( ):从集合里删除指定元素
>>> set1.add(6)
>>> set1
{1, 2, 3, 4, 5, 6}
>>> set1.remove(3)
>>> set1
{1, 2, 4, 5, 6}
>>> set1.add('a')
>>> set1
{1, 2, 4, 5, 6, 'a'}

frozenset( ): 创建一个不可修改的集合
>>> num2 = frozenset()
>>> num2
frozenset({0, 1, 2, 3, 4, 5})
>>> num2.add(6)
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module>
    num2.add(6)
AttributeError: 'frozenset' object has no attribute 'add'


set1 = {} 与 set1 = set() 是不一样的,前者会报错,后者会生成一个集合 {1,2}

报错的原因是:列表不是可哈希类型,列表是可变的
(集合跟字典的存储方式一样)
集合中相同元素的哈希值(存放地址) 是相同的,所有在集合中所有相同的元素会被覆盖,让集合中的元素拥有唯一性。
集合是按照地址查找的,不是顺序排放的,故集合是无序的!
所以, set1 这样的取值方法是会报错的,因为集合是无序的。

http://bbs.fishc.com/thread-45276-1-1.html
集合方法总结

我叫什么啊 发表于 2020-2-26 11:12:35

2020/2/26

029 文件

文件用后缀名来区分文件类型


open( ) : 打开文件(注意:斜杠要用转义字符转义)
>>> f = open('C:\\Users\\Aye\\Desktop\\Python练习\\020-String\\string1.txt')
>>> f
<_io.TextIOWrapper name='C:\\Users\\Aye\\Desktop\\Python练习\\020-String\\string1.txt' mode='r' encoding='cp936'>

文件对象方法:

f.close( ) 关闭文件
f.read(size == -1) 从文件读取 size 个字符,当未给定 size 时读取剩余所有字符,作为字符串返回
f.readline( ) 以写入模式打开文件,如果文件存在,则在文件末尾追加写入
f.write(str) 将字符串 str 写入文件
f.writelines(seq) 向文件写入字符串序列 seq , seq 应该是一个返回字符串的可迭代对象
f.seek(offset, from) 在文件中移动文件指针,从 from (0:文件起始位置;1:当前位置; 2:文件末尾位置)偏移 offset 个字节
f.tell() 返回当前在文件夹中的位置


f.read(): 按字符读取   f.readline( ): 按一行一行读取
在完成写入以后要及时关闭文件(f.close),因为Python 会缓存写入数据,若有断电等情况,写入将不被保存。

>>> f = open('C:\\Users\\Aye\\Desktop\\Python练习\\020-String\\string1.txt')
>>> f.read(10)
'%%$@_$^__#'
>>> f.tell()
10

文件还可用 list( ) 方法传换成列表

输出文件每行,先创建列表,再按行输出:
>>> f.seek(0,0)
0
>>> list(f)
['ACFlCTLIQlAIVMTqHFkswqbDDHtpgcWaXSSglUYKE\n', 'lqNsYCyaQXBzrFUbkAUAWAKrDgDtAlGMBqWQhpEwquZqWZJpslUfMllCwWptqINjrOBTLuPzwvXNbLCx\n', 'oFRritKRpJgBOaGPZdkUzvYnvYmAlEsVmKRXqyQUOdCBqLYyboOYeAQNLnkuiDXCiNiksSSRpDMVQQgs']
>>> f.seek(0,0)
0
>>> lines = list(f)
>>> for each_line in lines:
        print(each_line)

上面的方法效率不高,可改为用 for 将文件对象迭代出来:
>>> f.seek(0,0)
0
>>> for each_line in f:
        print(each_line)

写文件时, 第二个参数 w 当没有要打开的文件时会自动创建文件, 调用写入方法时返回的是输入的字符个数
>>> f1 = open('C:\\test.txt','w')
>>> f1.write('一二三四五')
5
>>> f1.close()

文件写完要关闭才能将数据存入文件中,否则只是在缓冲区



我叫什么啊 发表于 2020-2-26 18:40:17

031 文件系统

模块:一个包含所有你定义的函数和变量的文件,其后缀名是 .py , 模块可以被别的程序引入,以使用该模块中的函数等功能。

OS : 操作系统
常用的系统有:Windows、Mac OS、Linux、 UNIX等,这些操作系统底层对于文件系统的访问工作原理是不一样的,因此可能要针对不同的系统来考虑使用哪些文件系统模块...很麻烦

扩展阅读中有方法总结
>>> import os
>>> os.getcwd()
'C:\\Users\\Aye\\Desktop\\Python练习'
>>> os.chdir('F:\\')
>>> os.getcwd()
'F:\\'
>>> os.listdir('F:\\')
>>> os.mkdir('F:\\Python\\031-Test')
>>> os.mkdir('F:\\Python\\031-Test\\test1')


mkdir( path ): 本方法只能创建单层目录,如:031-Test存在后才能在其内创建test1
makedirs( path ): 递归创建多层目录,如果目录存在则抛出异常

rmdir( path ): 删除单层目录,目录不存在时则抛出异常
removedirs( path ): 递归删除目录,从子目录到父目录逐层尝试删除,遇到目录非空则抛出异常

相对路径 = 部分路径    绝对路径 = 完整路径

我叫什么啊 发表于 2020-3-7 20:52:15

2020/03/07

论一只爬虫的自我修养

Python的电池(?): urllib = url (统一资源定位器) + lib


URL的一般格式:
protocal://hostname[:port]/path/[;parameters][?query]#fragment

URL 由三部分组成:
① 协议:http, https, ftp, file, ed2k...
② 存放资源的服务器的域名系统或IP地址(有时候要包含端口号,http默认端口号为80)
③ 资源的具体地址,如目录或文件名等


我叫什么啊 发表于 2020-3-20 11:54:03

032永久存储

保存一个列表:
用 dump(file1, file2) 方法,将 文件file1 的数据“倒入” 文件file2 中。
用 load(file1) 方法 打开文件file1。
my_list = ]
#用pkl 后缀,用 wb 方式打开文件
pickle_file = open('my_list.pkl','wb') pickle.dump(my_list, pickle_file)
pickle_file.close()

#用 rb 方式打开
pickle_file = open('my_list.pkl', 'rb')
my_list2 = pickle.load(pickle_file)
print(my_list2)

我叫什么啊 发表于 2020-3-21 21:31:59

本帖最后由 我叫什么啊 于 2020-3-22 09:26 编辑

037 类和对象

对象=   属性 + 方法
Python中的类名约定以大写字母开头
类的属性定义应该尽可能的抽象,这样才更符合面向对象的思维

OO = Object Oriented面向对象

OO的特征:
1. 封装

2. 继承:子类自动共享父类之间的数据和方法的机制
>>> class MyList(list):
        pass

3. 多态:不同对象对同一方法响应不同的行动

>>> class A:
        def fun(self):
                print('I am A')

               
>>> class B:
        def fun(self):
                print('I am B')

               
>>> a = A()
>>> b = B()
>>> a.fun()
I am A
>>> b.fun()
I am B
(调用的方法一样,但是实现的结果不一样)


OOA:面向对象分析      OOP:面向对象编程   OOD:面向对象设计

Python中的 self 相当于 C++ 中的 this 指针(可是我也没学过C++)

self 是什么?
建房子根据图纸,虽然图纸一样但是有的房子不一样,主人也不一样,self 相当于门牌号。 由同一个类要生成无数个对象,对象都很相似,因为来自同一个属性和方法,当一个对象的方法被调用时,对象会将自身作为第一个参数传给 self 参数,接收到 self 后Python 就知道时哪个对象在调用方法了。

在类定义的时候要把 self 写进第一个位置
>>> class Ball:
        def setName(self, name):
                self.name = name
        def kick(self):
                print('My name is %s' % self.name)

               
>>> a = Ball()
>>> a.setName('AAA')
>>> b = Ball()
>>> b.setName('BBB')
>>> a.kick()
My name is AAA


Python 的魔法方法
通常被双下划线包围, 类似构造参数? 不太懂
__init__(self, param1, param2)
>>> class Ball:
        def __init__(self, name):
                self.name = name
        def kick(self):
                print('%s' % self.name)

               
>>> b = Ball('B')
>>> b.kick()
B



为了实现私有变量类似的特征,Python采用了一种 name mangling(名字改编),在Python 中定义私有变量只需要在变量名或函数名前加 ‘__’两个下划线,那么这个变量或函数就是私有的了。
>>> class Person2:
        __name = 'FishC'

       
>>> p = Person2()
>>> p.__name
Traceback (most recent call last):
File "<pyshell#62>", line 1, in <module>
    p.__name
AttributeError: 'Person2' object has no attribute '__name'
>>> p.name
Traceback (most recent call last):
File "<pyshell#63>", line 1, in <module>
    p.name
AttributeError: 'Person2' object has no attribute 'name'

>>> class Person2:
        __name = 'FishC'
        def getName(self):
                return self.__name

       
>>> p = Person2()
>>> p.getName()
'FishC'
>>> p.name
Traceback (most recent call last):
File "<pyshell#71>", line 1, in <module>
    p.name
AttributeError: 'Person2' object has no attribute 'name'
>>> p.__name
Traceback (most recent call last):
File "<pyshell#72>", line 1, in <module>
    p.__name
AttributeError: 'Person2' object has no attribute '__name'

Python 其实给双下划线改名了,改成了: _(1个下划线)类名__(2个下划线)变量名
>>> p._Person2__name
'FishC'


如果类中定义的方法想要访问属性值,要用 self :
class Person:
    name = '小甲鱼'
   
    def printName(self):
       print(self.name)

我叫什么啊 发表于 2020-4-6 21:46:57

本帖最后由 我叫什么啊 于 2020-4-6 22:53 编辑

Django 学习记录

安装虚拟环境
pip install virtualenv                # 安装虚拟环境

pip install virtualenvwrapper    # 安装虚拟环境扩展包


cd 到你要创建虚拟环境的路径下
virtualenv myproject()      #在myproject文件夹创建一个隔离的virtualenv环境

cd myproject
cd Scripts
activate                              # 在虚拟环境文件夹下的 Scripts 下 激活虚拟环境


安装Django 的时候出了问题,可能是网不行,好像要用什么镜像?

https://pypi.tuna.tsinghua.edu.cn/simple

百度试了一个方法( 还是在 Scripts 下安装)
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple django


创建django 项目:(可以创建个文件夹在文件夹里建项目)
django-admin startproject djDemo(项目名)


__init__.py : 说明test1 是一个 python 包
settings.py :项目的配置文件 (可在这里面配置使用哪些数据库)
urls.py : 进行 url 路由的配置
wsgi.py : web 服务器和Django 交互的入口
manage.py : 项目的管理文件


在Django开发中,一个功能模块用一个应用来实现
创建应用:(创建应用时要先进入项目目录)
pythonmanage.pystartapp***(应用名)



__init__.py : 说明 目录 是一个 python 包
views.py :接受请求,进行处理,与M、T进行交互,返回应答
models.py :
admin.py : 跟网站后台管理相关的文件
apps.py :
tests.py :写测试代码的文件 (测试人员写?)


要在 settings 文件里将 booktest 应用加入, 进行注册

然后通过 manage.py 运行项目(注意调用的路径): 用语句 python manage.py runserver

我叫什么啊 发表于 2020-4-8 09:18:45

ORM 框架

Object : 对象-类    Mapping :映射    Relations:关系,关系数据库中的表

通过类和对象操作对应的数据表,不需要写SQL语句

设计类:模型类 (在 model.py 中设置)
ORM另外一个作用:根据设计的类生成数据库中的表


模型类生成表:
1. 生成迁移文件 ,命令:
python manage.py makemigrations
迁移文件是根据模型类生成的

2. 执行迁移生成表, 命令:
Python manage.py migrate
根据迁移文件建立生成表

我叫什么啊 发表于 2020-4-8 09:35:51

本帖最后由 我叫什么啊 于 2020-4-8 10:15 编辑

Django 后台管理

1. 本地化
语言和时区的本地化,在setting 里面设置
LANGUAGE_CODE = 'zh-hans'    # 改成中文
TIME_ZONE = 'Asia/Shanghai'   # 中国时间,只能用上海的,没有北京的

2. 创建管理员,命令为:
Python manage.py createsuperuser

3. 注册模型类
在应用下的 admin.py 中注册模型类,告诉 django 框架根据注册的模型类来生成对应表管理页面
在页面中返回的时图书类的对象,如果要改显示的名字,要在models类中对返回值进行修改

b = BookInfo()
str(b)_str_

4. 自定义管理页面
在 admin 类中,自定义模型管理类。模型管理类就是告诉 django 在生成管理页面上显示哪些内容

我叫什么啊 发表于 2020-4-8 10:43:07

本帖最后由 我叫什么啊 于 2020-4-8 14:09 编辑

视图

在 Django 中, 通过浏览器去请求一个页面时,使用 视图函数 来处理这个请求。在 视图函数 处理之后,要给浏览器返回页面内容。

视图函数的使用:
1. 定义视图函数
在 views.py 中编写, 视图函数必须有一个参数 request, 进行处理以后,需要返回一个 HttpResponse 的类对象,括号里是返回给浏览器的内容

2. 进行 url 配置,建立 url 地址和视图的对应关系
(1)在booktest 里自己建立一个 urls.py文件
(2)在urls.py 和 views.py 里设置
(3)在djDemo1 的 urls.py 里配置项目 : path('', include('booktest.urls'))第一位是正则表达式,第二位是应用中的urls文件/ 视图函数名


启动服务器:
python manage.py runserver
(默认为: 127.0.0.1:8000)

当一个服务器打开一个页面后,要打开另一个页面可以指定另外一个服务器:
python manage.py runserver 127.0.0.1:8001

我叫什么啊 发表于 2020-4-9 19:57:07

Django 框架制作网页案例

编码前:
(1) 设计出访问页面的url 和对应的视图函数的名字,确定视图函数的功能
(2) 设计模板文件的名字

要求:
1. 完成图书信息的展示
(1)设计 url ,通过浏览器访问 http://127.0.0.1:8000/books 时显示图书信息页面
(2)设计 url 对应的视图函数 show_books:查询出所有图书的信息,将这些信息传递给模板文件
(3)编写模板文件 show_books.html, 遍历显示出每一本图书的信息

2. 完成点击某图书时,显示图书中所有英雄信息的页面

我叫什么啊 发表于 2020-4-9 20:00:29

我学的好累啊什么也不会也没人教啊我不想学了让我破罐子破摔了叭啊要了我的命啊太难啦啊天爷啊这是什么东西啊

我叫什么啊 发表于 2020-4-9 23:02:17

Django 模型管理器对象

BookInfo.objects.all() :
        object 是DJango帮助我们自动生成的管理器对象,通过这个管理器可以实现对数据的查询。object 是 models.Manger 类的一个对象,自定义管理器之后Django不再帮我们生成默认的 objects 管理器。

在 BookInfo 中自定义一个Manager对象:
# book = models.Manager()
objects = BookInfoManager()

1. 改变查询的结果集 , 例如: 查询isDelete 为 0 的结果集, 在models.py中:
class BookInfoManager(models.Manager):
        def all(self):
                books = super().all()   # 一个查询集 QuerySet
                # 对数据进行过滤
                books = books.filter(isDelete=False)
                return books

2. 封装方法 ,操作模型类对应的数据表(增删改查)
在模型类中:
def create_book(cls, btitle, bpub_date):
        obj = cls()
        obj.btitle = btitle
        obj.bpub_date = bpub_date
        obj.save()
        return obj

调用:
BookInfo.create_book('test1', '1999-1-1')          # 日期可以自动转换,但必须是传入合法的日期(格式?)

一般不定义在模型类中,在模型管理器中,修改如下:
class BookInfoManager(models.Manager):
        def all(self):
                books = super().all()   # 一个查询集 QuerySet
                # 对数据进行过滤
                books = books.filter(isDelete=False)
                return books
       
        def create_book(cls, btitle, bpub_date):
                book = BooInfo()          # 创建一个图书对象
                book.title = btitle
                book.bpub_date = bpub_date
                book.save()
                return book


原来的 object 管理类中也有插入信息的函数 create(),但是要根据关键字来输入参数
BookInfo.objects.create(btitle = 'test', bpub_date = '1999-1-1')

在创建图书对象时,模型类名字改变就会报错。每个模型管理对象都有个属性model,通过它可以获取其所在的模型类


book = BooInfo()   

改为:
model_class = self.model
book = model_class()





我叫什么啊 发表于 2020-4-9 23:16:58

可以用元选项 来指定数据库中对应的表名

在模型类中加入Meta 类,使用类属性 db_table = ' 。。。' :
class BookInfo(models.Model):
    .....

    class Meta:
      db_table = 'bookinfo'   #指定模型类对应的表名

指定以后再迁移也可在数据库里给名改了
页: [1] 2
查看完整版本: 学习总结