享受每一天,Just Enjoy !

0%

本文首发公众号: 伊洛的小屋,欢迎关注并查看更多内容!!!

HTMl简介
  • HTML(HyperText Markup Language) 不是一门编程语言,而是一种用来告知浏览器如何组织页面的标记语言
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    <p>伊洛yiluo 微信搜索:伊洛的小屋</p>
    </head>
    <body>

    </body>
    </html>

HTML5文档省略了<html>, <head>,<body>等元素,使用HTML5DOCTYPE声明文档类型,简化<meta>元素的charset属性值,省略<p> 元素的结束标记,使用<元素/> 的方式结束<meta>元素,以及
元素等语法知识要点。

1
2
3
4
5
6
7
<!DOCTYPE html>
<meta charset="UTF-8">
<title>HTML5基本语法</title>
<h1>HTML5的目标</h1>
<p>HTML5的目的是为了能够创建更简单的WEB程序,书写出更简洁的HTML代码</p>
<br/> 例如,为了是web程序的开发变得更容易,提供了更多api,为了使得html变得更简洁,开发出了新属性,新的元素等,总体来说
为下一代的web 平台提供了许许多多的功能
  • HTML 标签不区分大小写
    HTML包含
  • 开始标签
  • 结束标签
  • 内容
  • 元素
内容类型

html5的文件扩展名和内容类型保持不变。例如,扩展名仍然为'.html', '.htm'内容类型(ContentType)仍然为'text/html'

  • 文档类型
    DOCTYPE 命令声明文档类型,它是html文档必不可少的组成部分,且必须位于代码第一行。根据化繁为简的设计原则,html5对文档类型和字符说明都进行了简化
    在HTML5中,刻意不使用版本声明,一份文档将会适用于所有版本的HTML,在HTML5中,文档类型的声明方法如下
    1
    <!DOCTYPE html>
    当使用工具时,也可以再DOCTYPE声明中加入SYSTEM识别符,声明方法如下
    1
    <!DOCTYPE HTML SYSTEM "about:legacy-compat">
    在HTML5中,DOCTYPE声明方式是不区分大小写的,引号也不区分单引号还是双引号
  • 字符串编码
    在HTML5中,继续延用meta元素定义文档的字符编码,但是简化了charset属性的写法
    1
    <meta charset="UTF-8">
  • 标记省略
    在HTML5中,元素的标记可以省略。具体来说,元素的标记分为3种类型:不允许写结束标记,可以省略结束标记,开始标记和结束标记全部可以省略。
    不允许写结束标记的元素指,不允许使用开始标记与结束标记讲元素括起来的形式,只允许使用</元素>的形式进行书写
    1
    2
    <br>错误</br>
    </br> 正确
    嵌套元素
  • 一个元素放到其它元素之中,这被称作嵌套
    块级元素和内联元素
  • 块级元素在页面中以块的形式展现
  • 内联元素通常出现在块级元素中并环绕文档内容的一小部分,而不是一整个段落或者一组内容。内联元素不会导致文本换行
    空元素
  • 不是所有元素都拥有开始标签,内容,结束标签。一些元素只有一个标签,通常用来在此元素所在位置插入/嵌入一些东西。例如:元素<img>
    属性
    属性包含:
  • 一个空格,在属性和元素名称之间
  • 属性名称,后面跟着一个等于号
  • 一个属性值,由一对引号“ ”引起来
    属性值两边既可以用双引号,也可以用单引号。HTML5在此基础做了一些改进,当属性值不包括字符串、<、>、=、单引号、双引号等字符时,属性值两边的引号可以省略
    1
    2
    3
    <input type="text">
    <input type='text'>
    <input type=text>
    布尔属性
    没有值的属性,被称为布尔属性,只能有跟它的属性名一样的属性值
    对于具有boolean值的属性,例如disabled, readonly等,当只写属性而不指定属性时,表示属性值为true, 如果想要属性值设为false,可以不使用该属性。另外要想将属性设定为true,也可以将属性名设定为属性值,或将空字符串设定为属性值
    实例
    1
    2
    3
    4
    5
    6
    7
    8
    <!--只写属性,不写属性值,代表属性为true-->
    <input type="checkbox" checked>
    <!--不写属性,代表属性为false-->
    <input type="checkbox">
    <!--属性值=属性名,代表属性为true-->
    <input type="checkbox" checked="checked">
    <!--属性值=空字符串,代表为true-->
    <input type="checkbox" checked="">
    关注公众号获取更多内容

本文首发自伊洛的个人博客:https://yiluotalk.com,欢迎关注并查看更多内容!!!

1.生成器
  • Generator是一个用于创建迭代器的简单而强大的工具。 它们的写法类似标准的函数
  • 生成器首先它是一个迭代器,和迭代器一样,生成器只能被遍历迭代一次,因为每次迭代的元素不是像列表元素一样,已经在内存中,每迭代一次,生成一个元素
  • 生成器和迭代器的主要区别在于:
    1、它们的创建方式不同
    2、生成器有一些特殊方法是迭代器不具有的
    2.创建生成器的两中方法
    (一)yield 编写生成器函数,函数的返回值就是生成器
  • yield 的使用方法和return 类似。不同的是,return可以返回有效的 Python 对象,而 yield返回的是一个生成器,函数碰到 return 就直接返回了,而使用了 yield的函数,到yield 返回一个元素,当再次迭代生成器时,会从 yield 后面继续执行,直到遇到下一个yield或者函数结束退出
  • 承接上文迭代器,还是用游戏中的英雄技能举例子
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #!/usr/bin/python

    def hero(*skills):
    print('英雄的释放技能分别如下')
    for release_skill in skills:
    yield release_skill


    skill = hero('一骑当千','单刀赴会','青龙偃月','刀锋铁骑')
    for s in skill:
    print(s)
  • hero函数中传入英雄的1-4技能
  • 来看一下运行结果
    1
    2
    3
    4
    5
    6
    7
    8
    # 微信搜索:伊洛的小屋
    # 个人主页:https://yiluotalk.com/
    (yiluo) ➜ Code python hero.py
    英雄的释放技能分别如下
    一骑当千
    单刀赴会
    青龙偃月
    刀锋铁骑
  • 这样使用比迭代器的好处是,生成器不会像迭代器放在内存中,是用户传入数值动态生成的
    (二)生成器表达式
  • 另一种创建生成器的方式就是通过表达式
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    (yiluo) ➜  Code python3
    Python 3.7.5 (default, Nov 29 2019, 14:32:46)
    [Clang 9.0.0 (clang-900.0.39.2)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> s = (x+x for x in range(0,4))
    >>> s
    <generator object <genexpr> at 0x1058537d0>
    >>> for x in s:
    ... print(x)
    ...
    0
    2
    4
    6
  • s 就是生成器,然后遍历查看结果
  • 迭代完一次之后再迭代这个生成器,它不会打印元素,也不会报错
  • 使用生成器有什么好处呢?因为生成器不是把所有元素存在内存,而是动态生成的,所以当你要迭代的对象有非常多的元素时,使用生成器能为你节约很多内存,这是一个内存友好的特性

关注公众号获取更多内容

1.迭代器

要理解迭代器,首先需要明白迭代器和可迭代对象的区别。一个一个读取、操作对象称为迭代,Python 中,可迭代(Iterable)对象就是你能用for循环迭代它的元素,比如列表是可迭代的

  • 大多数容器对象都可以使用 for 语句,承接上文装饰器的例子,还是拿英雄的技能举例子

  • 王者荣耀中英雄关羽的技能有一骑当千 单刀赴会 青龙偃月 刀锋铁骑for语句分别迭代出1-4技能

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    (yiluo) ➜  Code python3
    Python 3.7.5 (default, Nov 29 2019, 14:32:46)
    [Clang 9.0.0 (clang-900.0.39.2)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> skills = ['一骑当千','单刀赴会','青龙偃月','刀锋铁骑']
    >>> for skill in skills:
    ... print(skill)
    ...
    一骑当千
    单刀赴会
    青龙偃月
    刀锋铁骑
  • 在幕后,for 语句会调用容器对象中的 iter()。 该函数返回一个定义了 __next__() 方法的迭代器对象,该方法将逐一访问容器中的元素

  • 我们现在利用一下 iter()函数 和 next()函数

你能用 next 函数不断的去获取它的下一个值,直到迭代器返回 StopIteration异常。所有的可迭代对象都可以通过 iter 函数去获取它的迭代器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 作者:伊洛Yiluo 公众号:伊洛的小屋
# 个人主页:https://yiluotalk.com/
# 博客园:https://www.cnblogs.com/yiluotalk/
>>> skills = ['一骑当千','单刀赴会','青龙偃月','刀锋铁骑']
>>> skill = iter(skills)
>>> print(skill)
<list_iterator object at 0x1037ea5d0>
>>> next(skill)
'一骑当千'
>>> next(skill)
'单刀赴会'
>>> next(skill)
'青龙偃月'
>>> next(skill)
'刀锋铁骑'
>>> next(skill)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
  • skill就是迭代器
  • next迭代到没有值的时候就会报错
  • 所有的迭代器其实都实现了__iter____next__ 这俩个魔法方法,iternext 函数实际上调用的是这两个魔法方法,上面的例子背后其实是这样的
2.另一种实现方式
  • 迭代器的另一种实现方式,__iter__ + __next__:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    >>> class Test:
    ... def __init__(self, a, b):
    ... self.a = a
    ... self.b = b
    ... def __iter__(self):
    ... return self
    ... def __next__(self):
    ... self.a += 1
    ... if self.a > self.b:
    ... raise StopIteration()
    ... return self.a
    ...
    >>> test = Test(0, 5)
    >>> next(test)
    1
    >>> next(test)
    2
    >>> next(test)
    3
    >>> next(test)
    4
    >>> next(test)
    5
    >>> next(test)
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<stdin>", line 10, in __next__
    StopIteration
  • 能被 for 循环访问的都是可迭代对象,能被 next 函数获取下一个值的是迭代器

欢迎下方【戳一下】【点赞】
Author:伊洛Yiluo
愿你享受每一天,Just Enjoy !

1.装饰器定义
  • 装饰器本质上是一个函数,可以接受一个函数作为参数
    2.装饰器简单的例子
  • 承接之前的内容,英雄释放火焰技能。打印出英雄释放技能的时间
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    #!/usr/bin/python
    from datetime import datetime

    def release_skills(hero):
    def release_skill(*skill, **skills):
    print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
    return hero(*skill, **skills)
    return release_skill


    @release_skills
    def hero(name, skill):
    return (name + '-->'+'释放技能:'+ skill)


    print(hero('关羽', 'fire'))
    print(hero.__name__)
  • 如上,release_skills装饰器负责打印释放技能的时间
    1
    2
    3
    4
    (yiluo) ➜  Code python hero.py
    2019-12-12 11:11:49
    关羽-->释放技能:fire
    release_skill
  • 我们运行hero函数的时候,同时打印出了英雄释放火焰技能的时间
  • 可是我们发现了一个比较严重的问题,hero 函数应变成了release_skill函数了,看上面的代码,确实hero已经被release_skill改变了
  • 那如何解决这个被改变的问题呢? 总不能用完装饰器,被装饰的函数已经不是之前的函数吧,还好Python 提供了方法解决这个问题
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # 作者:伊洛Yiluo 公众号:伊洛的小屋
    # 个人主页:https://yiluotalk.com/
    # 博客园:https://www.cnblogs.com/yiluotalk/
    #!/usr/bin/python
    from datetime import datetime
    from functools import wraps

    def release_skills(hero):
    @wraps(hero)
    def release_skill(*skill, **skills):
    print(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
    return hero(*skill, **skills)
    return release_skill


    @release_skills
    def hero(name, skill):
    return (name + '-->'+'释放技能:'+ skill)


    print(hero('关羽', 'fire'))
    print(hero.__name__)
  • 上面的代码用到了wraps(),然后我们运行一下看下结果函数是否被改变
    1
    2
    3
    4
    (yiluo) ➜  Code python hero.py
    2019-12-12 11:25:38
    关羽-->释放技能:fire
    hero
  • 函数依旧是hero,看来是完美解决了这个问题
  • @Python 提供的语法糖,语法糖指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用
    3.property 装饰器
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/bin/env python3

    class Animal:
    def __init__(self):
    self.age = 3


    if __name__ == "__main__":
    cat = Animal()
    print(cat.age)
    cat.age = 'age'
    print(cat.age)
  • 执行结果
    1
    2
    3
    ➜  code python3 demo.py
    3
    age
  • 以看到如果 age 属性值可以被公开访问,用户赋值为字符串,很明显这不符合实际情况
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #!/usr/bin/env python3

    class Animal:
    def __init__(self):
    self.__age = 3
    def get_age(self):
    return self.__age
    def set_age(self, value):
    if isinstance(value, int):
    self.__age = value
    else:
    raise ValueError


    if __name__ == "__main__":
    cat = Animal()
    print(cat.get_age)
    cat.set_age('age')
  • 执行结果
    1
    2
    3
    4
    5
    6
    Traceback (most recent call last):
    File "demo.py", line 18, in <module>
    cat.set_age('age')
    File "demo.py", line 12, in set_age
    raise ValueError
    ValueError
  • @property 装饰器可以将一个方法变成一个属性来使用,通过 @property 装饰器可以获得和修改对象的某一个属性。
  • 使用 @property 装饰器的方法如下:

1.只有 @property 表示只读
2.同时有 @property 和 @.setter 表示可读可写
3.同时有 @property、@
.setter、和 @.deleter 表示可读可写可删除
4.@property 必须定义在 @
.setter 的前面
5.类必须继承 object 父类,否则 @property 不会生效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env python3

class Animal:
def __init__(self):
self.__age = 3
@property
def age(self):
return self.__age
@age.setter
def age(self, value):
if isinstance(value, int):
self.__age = value
else:
raise ValueaError
@age.deleter
def age(self):
print('delete age')
del self.__age

if __name__ == "__main__":
cat = Animal()
print(cat.age)
cat.age = 6
print(cat.age)
del cat.age
print(cat.age)
  • 执行结果
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ➜  code python3 demo.py
    3
    6
    delete age
    Traceback (most recent call last):
    File "demo.py", line 26, in <module>
    print(cat.age)
    File "demo.py", line 8, in age
    return self.__age
    AttributeError: 'Animal' object has no attribute '_Animal__age'
  • 从这个简单的例子中我们可以发现 age 由一个函数转变为一个属性,并且通过增加一个 setter 函数的方式来支持 age 的设置。通过 property 和 setter ,可以有效地实现 get_age(获取对象的属性) 和 set_age(设置对象的属性)这两个操作,而不需要直接将内部的 __age 属性暴露出来,同时可以在 setter 函数中对设置的参数进行检查,避免了直接对 __age 内部属性进行赋值的潜在风险

欢迎下方【戳一下】【点赞】
Author:伊洛Yiluo
愿你享受每一天,Just Enjoy !

1.使用模板系统
  • 在之前的model.py文件中新增加Detail

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    from django.db import models

    # Create your models here.


    class ProjectInfo(models.Model):
    """ 项目信息模型 """
    project_name = models.CharField(max_length=30)
    dev = models.CharField(max_length=20)
    tester = models.CharField(max_length=20)
    add_data = models.DateTimeField(auto_now_add=True)

    def __str__(self):
    # 返回项目名称
    return self.project_name


    class Detail(models.Model):
    project = models.ForeignKey(ProjectInfo, on_delete=models.CASCADE)
    detail_text = models.CharField(max_length=200)

    def __str__(self):
    return self.detail_text

    使用 ForeignKey定义了一个关系。这将告诉 Django,每个 detail 对象都关联到一个 ProjectInfo 对象。Django 支持所有常用的数据库关系:多对一、多对多和一对一

  • 在管了后台添加数据

  • 对应项目添加详情

  • 重新改写一下project.html的模板

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>AutoPlarform Home</title>
    </head>
    <body>
    <h1>{{ project.project_name }}</h1>
    {% for detail in project.detail_set.all %}
    <li>{{ detail.detail_text }}</li>
    {% endfor %}
    </body>
    </html>

    模板系统统一使用点符号来访问变量的属性

  • 现在我们来访问下每个项目对应的url,来看一下项目的信息详情有没有正确的显示出来


    显示内容正确

    2. 去除模板中的硬编码URL
  • 我们修改一下之前home的页面,让对应内容可以跳转

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>AutoPlarform Home</title>
    </head>
    <body>
    {% if project_list %}
    <ul>
    {% for project in project_list %}
    <li>
    <a href="/autoapi/{{ project.id }}/">{{ project.project_name }}</a>
    </li>
    {% endfor %}
    </ul>
    {% endif %}

    </body>
    </html>
  • 打开home页面

  • 然后点击接口自动化

    成功跳转到接口自动化的介绍页面

  • 但是以上内容你会发现一个问题,我们的挑战链接是硬编码的

    1
    <a href="/autoapi/{{ project.id }}/">{{ project.project_name }}</a>

    硬编码和强耦合的链接,对于一个包含很多应用的项目来说,修改起来是十分困难的
    不过的还记得之前在url配置页面的内容嘛

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 作者:伊洛Yiluo 公众号:伊洛的小屋
    # 个人主页:https://yiluotalk.com/
    # 博客园:https://www.cnblogs.com/yiluotalk/
    from django.urls import path
    from . import views


    urlpatterns = [
    path('home/', views.home, name='index'),
    path('<int:project_id>/', views.project_list, name='project list'),
    path('register/', views.register, name='register'),
    ]

    之前我们通过name参数为url定义了名字,现在我们可以通过% url %代替它

  • 来改一下home.html代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>AutoPlarform Home</title>
    </head>
    <body>
    {% if project_list %}
    <ul>
    {% for project in project_list %}
    <li>
    <a href="{% url 'project list' project.id %}">{{ project.project_name }}</a>
    </li>
    {% endfor %}
    </ul>
    {% endif %}

    </body>
    </html>
  • 再次打开一个页面验证下跳转

    成功的跳转

  • 这样做的好处也可以不动模板的内容改URL

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from django.urls import path
    from . import views


    urlpatterns = [
    path('home/', views.home, name='index'),
    path('detail/<int:project_id>/', views.project_list, name='project list'),
    path('register/', views.register, name='register'),
    ]
  • 打开home首页点击跳转

    URL已经按预设置发生了变化

    3.为URL名称添加命名空间

    现在再Django项目中,只有一个APP,但是实际开发过程中会有很多。Django如何分辨重名的URL
    答案就是:在URLconf中添加命名空,加上app_name 设置命名空间

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from django.urls import path
    from . import views


    app_name = 'autoapi'
    urlpatterns = [
    path('home/', views.home, name='index'),
    path('detail/<int:project_id>/', views.project_list, name='project list'),
    path('register/', views.register, name='register'),
    ]

    HTML页面再改动下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>AutoPlarform Home</title>
    </head>
    <body>
    {% if project_list %}
    <ul>
    {% for project in project_list %}
    <li>
    <a href="{% url 'autoapi:project list' project.id %}">{{ project.project_name }}</a>
    </li>
    {% endfor %}
    </ul>
    {% endif %}

    </body>
    </html>
  • 打开网页查看效果

关注公众号获取更多内容

1.类中的特殊方法(魔法方法)
  • 在 Python 中有一些特殊的方法,它们是 Python 内置的方法,通常以双下划线来命名,比如__init____repr__ 等等,在类中使用它们时往往较少的代码就可以发挥很大的作用,提高开发效率,因此在 Python 中称这些方法为“魔法方法”
  • 在 Python 中最常使用的是__init__方法,它可以用于新建实例对象的时候给对象绑定属性,但是在新建对象的时候第一个调用的不是__init__方法,而是 __new__(cls, [...])方法,这两个方法的区别在于

1.__init__方法是在实例对象创建完成后调用的,主要用于设置实例对象的初始值,它的第一个参数为 self,可以不需要返回值
2. __new__方法是在实例对象被创建之前调用的,主要用于创建实例对象并返回实例对象,它的第一个参数为cls ,它只会取 cls参数,其余参数都传给了 __init__方法,必须要有返回值可以是 super().__new__(cls) 或是 object.__new__(cls)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 作者:伊洛Yiluo 公众号:伊洛的小屋
# 个人主页:https://yiluotalk.com/
# 博客园:https://www.cnblogs.com/yiluotalk/
In [1]: class People:
...: def __new__(cls, name):
...: print('__new__')
...: return super(People, cls).__new__(cls)
...: def __init__(self, name):
...: print('__init__')
...: self.name = name
...: def __del__(self):
...: print('__del__')
...:

In [2]: man = People('Yiluo')
__new__
__init__

In [3]: man.name
Out[3]: 'Yiluo'

In [4]: del man
__del__
  • 由于 Python 是动态语言,因此定义一个实例对象后可以绑定任意的属性,如果需要限制绑定属性类别,可以使用__slots__ 变量,可以绑定的属性值以元组的形式赋予给它。需要注意的是:__slots__的作用只在定义的类中有效,在继承该类的子类中是无效的。如果想要在子类中限制属性则需要重新定义,重新定以后,父类中的__slots__则会被子类继承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
>>> class People:
... __slots__ = ('name', 'age')
...
>>> somebody = People()
>>> somebody.name = 'Yiluo'
>>> somebody.age = 18
>>> somebody.name
'Yiluo'
>>> somebody.age
18
>>>
>>> class Man(People):
... __slots__ = ('city')
...
>>> person = Man()

>>> person.name = 'Yiluo'
>>> person.age = 18
>>> person.address = 'shenzhen'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Man' object has no attribute 'address'
>>> person.city = 'shenzhen'
>>> person.name
'Yiluo'
>>> person.age
18
>>> person.city
'shenzhen'
2. __getattribute____getattr__
  • 在 Python 类中,当访问实例对象属性的时候,其实默认会调用__getattribute__方法,如果没有该属性就会报 AttributeError 错误,这个时候可以考虑使用 __getattr__方法进行自定义
3.__call__
  • 在 Python 中一切皆对象,对象分为可调用的和不可调用的,凡是可以通过一对括号 () 来调用的都是可调用对象,比如函数、类等,可以通过 callable() 函数来判断一个对象是否是可调用对象
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> class People:
    ... pass
    ...
    >>> person = People()
    >>> callable(person)
    False
    >>> callable(People())
    False
    >>> callable(People)
    True
    >>>
  • 通常情况下实例对象都是不可调用对象,但是如果在类中使用了 call 方法就可以将实例对象转换为可调用对象
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> class People:
    ... def __call__(self):
    ... print('__call__')
    ...
    >>> person = People()
    >>> person()
    __call__
    >>> callable(person)
    True
    4.__iter____next__
  • 使用 __iter__方法就可以让类成为一个可迭代对象,如果使用 for 循环遍历类对象还需要在类中定义__next__方法,在__next__方法中可以定义取值的规则,当超出取值规则会抛出 StopIteration 异常从而退出当前循环
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #!/usr/bin/env python3

    class Test:
    def __init__(self, data=0):
    self.data = data
    def __iter__(self):
    return self
    def __next__(self):
    if self.data > 5:
    raise StopIteration
    else:
    self.data += 1
    return self.data

    for i in Test():
    print(i)
  • 执行结果
    1
    2
    3
    4
    5
    6
    7
    ➜  code python3 demo.py
    1
    2
    3
    4
    5
    6

关注公众号获取更多内容

1.抛出404错误
  • 当内容不存在时,需要返回404

  • 回到views.py,改写project_list

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    from django.http import HttpResponse, Http404
    from django.shortcuts import render

    from .models import ProjectInfo

    # Create your views here.


    def home(request):
    project_list = ProjectInfo.objects.order_by('add_data')[:5]
    context = {'project_list': project_list}
    return render(request, 'autoapi/home.html', context)


    def project_list(request, project_id):
    try:
    project = ProjectInfo.objects.get(pk=project_id)
    context = {'project': project}
    except ProjectInfo.DoesNotExist:
    raise Http404('project list dose not exist')
    return render(request, 'autoapi/project.html', context)


    def register(request):
    return HttpResponse('You\'re looking at the register page')
  • 回到url.py 改写一下, project_list

    1
    2
    3
    4
    5
    6
    7
    8
    9
    from django.urls import path
    from . import views


    urlpatterns = [
    path('home/', views.home, name='index'),
    path('<int:project_id>/', views.project_list, name='project list'),
    path('register/', views.register, name='register'),
    ]
  • 在/AutoPlatform/autoapi/templates下新建一个project.html文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>AutoPlarform Home</title>
    </head>
    <body>
    {{ project }}
    </body>
    </html>
  • 来先看下全面的列表

  • 数据中只有4个列表,那么如果输入id 为5的话,按照上面的代码逻辑应该就会抛出404异常的错误了

  • 来先看看id = 1

  • 再看看id = 4

  • 边界值都看过了,那么现在我们来输入一个不存在数据的id,测试一下是否会抛出404的异常

  • 抛出了project list dose not exist的异常

    2.快捷函数: get_object_or_404()

    Django还提供了一个快捷的函数来实现上面的功能

  • 现在来再改写一个views.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    # 作者:伊洛Yiluo 公众号:伊洛的小屋
    # 个人主页:https://yiluotalk.com/
    # 博客园:https://www.cnblogs.com/yiluotalk/
    from django.http import HttpResponse
    from django.shortcuts import get_object_or_404, render

    from .models import ProjectInfo

    # Create your views here.


    def home(request):
    project_list = ProjectInfo.objects.order_by('add_data')[:5]
    context = {'project_list': project_list}
    return render(request, 'autoapi/home.html', context)


    def project_list(request, project_id):
    project = get_object_or_404(ProjectInfo, pk=project_id)
    context = {'project': project}
    return render(request, 'autoapi/project.html', context)


    def register(request):
    return HttpResponse('You\'re looking at the register page')
  • 打开一个存在的id

  • 打开一个不存在的id

  • 这样就简化了一开始的过程,看上去更加的简洁,而且会降低模型层和视图层的耦合性

欢迎下方【戳一下】【点赞】
Author:伊洛Yiluo
愿你享受每一天,Just Enjoy !

1. 创建主页
  • 使用Django创建网页的过程通常分三个阶段:定义URL、编写视图和编写模板
  • 每个URL都被映射到特定的视图,视图函数获取并处理网页所需的数据
    2.编写更多视图
  • 现在在views.py 里添加更多视图
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    from django.http import HttpResponse

    # Create your views here.


    def home(request):
    return HttpResponse("Hello, Welcome to Home Page")


    def project_list(request):
    return HttpResponse('You\'re looking at the list of project list')


    def register(request):
    return HttpResponse('You\'re looking at the register page')
  • 把这些新视图添加进 urls 模块里
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    # 作者:伊洛Yiluo 公众号:伊洛的小屋
    # 个人主页:https://yiluotalk.com/
    # 博客园:https://www.cnblogs.com/yiluotalk/
    from django.urls import path
    from . import views


    urlpatterns = [
    path('home/', views.home, name='index'),
    path('project_list/', views.project_list, name='project list'),
    path('register/', views.register, name='register'),
    ]
  • 分别输入网址查看结果

3. 写一个真正有用的视图
  • 每个视图必须要做的只有两件事:返回一个包含被请求页面内容的 [HttpResponse]对象,或者抛出一个异常,比如 [Http404]
  • 回到views.py
  • 之前我们在管理后台添加过project的数据
  • 来修改一下主页的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from django.http import HttpResponse
from .models import ProjectInfo

# Create your views here.


def home(request):
project_list = ProjectInfo.objects.order_by('add_data')[:5]
output = ', '.join([q.project_name for q in project_list])
return HttpResponse(output)


def project_list(request):
return HttpResponse('You\'re looking at the list of project list')


def register(request):
return HttpResponse('You\'re looking at the register page')
  • 打开网页查看

    内容已经成功的展示
    4.模板
  • 虽然上面实现了暂时页面,但是存在一个比较严重的问题。内容是写在代码里面的,这样不适合管理。下面创建一个视图,就可以将页面的设计从代码中分离出来
  • 首先来创建一个templates 目录,用来存放静态文件,再创建一个目录 autoapi,然后在其中新建一个文件home.html
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>AutoPlarform Home</title>
    </head>
    <body>
    {% if project_list %}
    <ul>
    {% for project in project_list %}
    <li>
    <a href="/autoapi/register/">{{ project.project_name }}</a>
    </li>
    {% endfor %}
    </ul>
    {% endif %}

    </body>
    </html>
  • 下面在更新下views.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    from django.http import HttpResponse
    from django.template import loader

    from .models import ProjectInfo

    # Create your views here.


    def home(request):
    project_list = ProjectInfo.objects.order_by('add_data')[:5]
    template = loader.get_template('autoapi/home.html')
    context = {
    'project_list': project_list,
    }
    return HttpResponse(template.render(context, request))


    def project_list(request):
    return HttpResponse('You\'re looking at the list of project list')


    def register(request):
    return HttpResponse('You\'re looking at the register page')
  • 我们来打开主页查看下有没有效果
  • 信息成功的显示在了主页上
    5.一个快捷函数: render()
  • Django 提供了一个快捷函数,我们用它来重写views.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    from django.http import HttpResponse
    from django.shortcuts import render

    from .models import ProjectInfo

    # Create your views here.


    def home(request):
    project_list = ProjectInfo.objects.order_by('add_data')[:5]
    context = {'project_list': project_list}
    return render(request, 'autoapi/home.html', context)


    def project_list(request):
    return HttpResponse('You\'re looking at the list of project list')


    def register(request):
    return HttpResponse('You\'re looking at the register page')
  • 再次刷新主页查看一下效果
  • 同刚才是一个效果
    关注公众号获取更多内容

1. 面向对象编程简介

面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有对象概念的程序编程典范,同时也是一种程序开发的抽象方针。它可能包含数据属性代码方法。对象则指的是的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关连的数据。在面向对象程序编程里,计算机程序会被设计成彼此相关的对象(引自维基百科)

2.面向对象4个核心概念
  • 抽象

  • 封装

  • 继承

  • 多态
    ######3.类的定义

  • 类和对象
    面向对象的两个基本概念实例,而实例是根据类创建出来的一个个具体的“对象”,一个类中既会定义属性,也会定义方法

  • 类的命名规则遵循大驼峰命名法:每个单词的第一个字母都大写,私有类使用下划线开头

    1
    2
    3
    4
    5
    6
    class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>
  • 下面定义一个People的类,并且实例化为student

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    >>> class People():
    ... pass
    ...
    >>> student = People()
    >>> print(student)
    <__main__.People object at 0x10e1796d0>
    >>> People()
    <__main__.People object at 0x10e179750>
    >>> People
    <class '__main__.People'>
    >>> student.name = 'yiluo'
    >>> student.name
    'yiluo'
  • 0x10e1796d0为内存地址

  • 实例方法
    Python 中只要新建一个类就会自动创建它的内置类方法属性,可以通过 dir(类名)查看

    1
    2
    3
    4
    5
    >>> class People():
    ... pass
    ...
    >>> dir(People)
    ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
  • 其中最常用的是 __init__ 方法,它可以对实例进行初始化设置(类的内置方法前后各有两个下划线 _,简称:“双下划线”)

  • 下面重新写一个类并初始化名字

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    (yiluo) ➜  Code touch people.py
    (yiluo) ➜ Code vim people.py
    #!/usr/bin/python3

    class People():
    def __init__(self):
    self.name = 'yiluo'


    student = People()
    print(student.name)
  • 执行文件打印出了名字

    1
    2
    (yiluo) ➜  Code python people.py
    yiluo
  • 类中的函数通常称作方法,self所指的是就是实例本身,下面修改下类中的属性,也就是年龄

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 作者:伊洛Yiluo 公众号:伊洛的小屋
    # 个人主页:https://yiluotalk.com/
    # 博客园:https://www.cnblogs.com/yiluotalk/
    #!/usr/bin/python3

    class People():
    def __init__(self, name):
    self.name = name
    self.age = '20'

    student = People('yiluo')
    print(student.name)
    student.age = '18'
    print(student.age)
  • 年龄被修改为了18岁

    1
    2
    3
    (yiluo) ➜  Code python people.py
    yiluo
    18
  • __repr__ 来格式化实例的打印格式

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #!/usr/bin/python3

    class People():
    def __init__(self, name, age):
    self.name = name
    self.age = age

    def __repr__(self):
    return 'Student: {}'.format(self.name)


    student = People('yiluo', 20)
    print(student.name)
    print(student.age)
    print(student)
  • 格式化打印输出

    1
    2
    3
    4
    (yiluo) ➜  Code python people.py
    yiluo
    20
    Student:yiluo

    ![](https://imgconvert.csdnimg.cn/aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy81OTU5NTUxLTIyNzhlZmYzMzU4ZGI5NTQuanBlZw?x-oss-process=image/format,png)
4.类的封装

面向对象的语言中,封装就是用类将数据基于数据的操作封装在一起,隐藏内部数据,对外提供公共的访问

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/usr/bin/python3

class People():
def __init__(self, name, age):
self._name = name
self._age = age

def get_name(self):
return self._name

def get_age(self):
return self._age

def set_name(self, name):
self._name = name

def set_age(self, age):
self._age = age

def score(self, score):
print('姓名:{}'.format(self.get_name()) + ' '+ '年龄:{}'.format(self.get_age())+ ' ' + '得分:{}'.format(score) )

# 创建实例对象student
student = People('yiluo', '20')
student.get_name()
student.get_age()
student.score('98')

#重新设置名字和年龄
student.set_name('luoyi')
student.set_age('19')

#重新获得名字和年龄
student.get_name()
student.get_age()
student.score('99')
  • Python 的私有属性用一个或两个下划线开头表示,一个下划线表示外部调用者不应该直接调用这个属性,但其实还是可以调用的; 如果是两个下划线就不能调用
  • 执行一下,看下结果
    1
    2
    3
    (yiluo) ➜  Code python people.py
    姓名:yiluo 年龄:20 得分:98
    姓名:luoyi 年龄:19 得分:99
    5.类的继承与方法重写
  • 继承分为两种:单继承多继承单继承是指子类只继承于一个父类,相应的多继承是指子类继承于多个父类
  • 单继承方法重写
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #!/usr/bin/python3

    class People(object):
    def __init__(self, name, age):
    self._name = name
    self._age = age

    def get_name(self):
    return self._name

    def get_age(self):
    return self._age

    def set_name(self, name):
    self._name = name

    def set_age(self, age):
    self._age = age

    def title(self):
    pass


    class Student(People):
    def title(self):
    print('姓名{}'.format(self.get_name()) + ' ' + '年龄{}'.format(self.get_age()) + ' ' + '职业:学生')


    class Teacher(People):
    def title(self):
    print('姓名{}'.format(self.get_name()) + ' ' + '年龄{}'.format(self.get_age()) + ' ' + '职业:教师')


    student = Student('yiluo', '20')
    teacher = Teacher('luoyi', '19')
    student.title()
1
2
3
(yiluo) ➜  Code python people.py
姓名yiluo 年龄20 职业:学生
姓名luoyi 年龄19 职业:教师
  • 所谓重写父类的方法就是指:在子类中定义和父类同名的方法,那么子类中的该方法就会覆盖掉父类中对应的方法
    6.类的多继承
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    # 作者:伊洛Yiluo 公众号:伊洛的小屋
    # 个人主页:https://yiluotalk.com/
    # 博客园:https://www.cnblogs.com/yiluotalk/
    class Name():
    def __init__(self):
    self.name = 'yiluo'
    def demo1(self):
    print('打印名字')

    class Age():
    def __init__(self):
    self.age = 20
    def demo2(self):
    print('打印年龄')


    class Somebody(Name, Age):
    def __init__(self):
    Name.__init__(self)
    Age.__init__(self)
    def demo3(self):
    print('打印某人')

    somebody = Somebody()
    print(somebody.name)
    print(somebody.age)
    somebody.demo1()
    somebody.demo2()
    somebody.demo3()
    1
    2
    3
    4
    5
    6
    yiluo) ➜  Code python demo.py
    yiluo
    20
    打印名字
    打印年龄
    打印某人
    7.多态
    多态就是使用同一方法对不同对象可以产生不同的结果
    8.私有属性和方法
  • Python 在属性方法名前添加 __两个下划线 __)来拒绝外部的访问
  • 两个下划线是设置私有属性/方法的标准样式, 还有一种设置私有属性/方法的样式,就是在属性/方法名字前加一个下划线_ 但是其实这样的私有属性/方法只仅仅是视为不能直接访问,但是实际上还是可以访问的
    9.类属性,类方法
    类属性类方法是可以直接使用类访问,不需要实例化
  • 类属性
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> class Hero(object):
    ... skill = 'fire'
    ... def __init__(self, name):
    ... self._name = name
    ...
    >>> Hero.skill
    'fire'
    >>> xiangyu= Hero('项羽')
    >>> xiangyu.skill
    'fire'

    1.创建一个英雄类

2.英雄的技能是火焰
3.初始化英雄的名字
4.实例一个英雄
5.调用英雄的技能属性

  • 类方法
    类方法用装饰器 @classmethod装饰,类方法中可以访问类属性
    类方法的第一个参数传入的是类对象,而不是实例对象,约定俗成的,类方法中要指代类对象本身都使用 cls
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    >>> class Hero(object):
    ... skill = 'fire'
    ... def __init__(self, name):
    ... self._name = name
    ... @classmethod
    ... def get_skill(cls):
    ... return cls.skill
    ...
    >>> Hero.get_skill()
    'fire'
    >>> liubei = Hero('刘备')
    >>> liubei._name
    '刘备'
    >>> liubei.get_skill()
    'fire'

    1.不需要实例化就可以调用

  • 静态方法
    静态方法用装饰器 @staticmethod 装饰,和 @classmethod 有点类似。静态方法在运行时不需要实例的参与,并且也不需要传递cls
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/bin/python3

    class Hero(object):
    skill = 'fire'
    def __init__(self, name):
    self._name = name
    @staticmethod
    def release_skills():
    print(guanyu._name + ' ' +'释放技能' + ': '+ Hero.skill)

    guanyu = Hero('关羽')
    Hero.release_skills()

    1.静态方法 ,英雄释放技能

2.不需要实例化直接释放火焰技能

1
2
(yiluo) ➜  Code python test.py
关羽 释放技能: fire

10.property 装饰器

@property 装饰器可以将一个方法变成一个属性来使用,通过 @property 装饰器可以获得和修改对象的某一个属性

@property 表示只读
@property 和 @.setter 表示可读可写
@property、@
.setter、和 @.deleter 表示可读可写可删除
@property 必须定义在 @
.setter 的前面
类必须继承 object 父类,否则 @property 不会生效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/python3

class Hero(object):
skill = 'fire'
def __init__(self, name):
self._name = name
@property
def name(self):
return self._name
@name.setter
def name(self, value):
if isinstance(value, str):
self._name = value
else:
raise ValueError
@name.deleter
def name(self):
print('del name')
del self._name


liubei = Hero('刘备')
print(liubei.name)
liubei.name = '关羽'
print(liubei.name)
liubei.name = 100
1
2
3
4
5
6
7
8
9
(yiluo) ➜  Code python test.py
刘备
关羽
Traceback (most recent call last):
File "test.py", line 26, in <module>
liubei.name = 100
File "test.py", line 15, in name
raise ValueError
ValueError

1.这样的好处是可以在方法中对用户传入的数据进行校验(校验了英雄名称是字符串)

  • 删除英雄
    1
    2
    3
    4
    5
    6
    liubei = Hero('刘备')
    print(liubei.name)
    liubei.name = '关羽'
    print(liubei.name)
    del liubei.name
    print(liubei.name)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    (yiluo) ➜  Code python test.py
    刘备
    关羽
    删除名字
    Traceback (most recent call last):
    File "test.py", line 27, in <module>
    print(liubei.name)
    File "test.py", line 9, in name
    return self._name
    AttributeError: 'Hero' object has no attribute '_name'
    1.英雄已经被成功删除

如果你觉得文章对你有些帮助,欢迎微信搜索「伊洛的小屋」第一时间阅读

关注公众号获取更多内容

1.Django Shell
  • 打开Django的命令交互模式
1
2
3
4
5
6
(django) ➜  AutoPlatform python manage.py shell
Python 3.7.5 (default, Nov 29 2019, 14:32:46)
[Clang 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
  • 还记得之前模型嘛
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 作者:伊洛Yiluo 公众号:伊洛的小屋
# 个人主页:https://yiluotalk.com/
# 博客园:https://www.cnblogs.com/yiluotalk/
from django.db import models

# Create your models here.


class ProjectInfo(models.Model):
""" 项目信息模型 """
project_name = models.CharField(max_length=30)
dev = models.CharField(max_length=20)
tester = models.CharField(max_length=20)
add_data = models.DateTimeField(auto_now_add=True)

def __str__(self):
# 返回项目名称
return self.project_name
  • 尝试用Shell操作一下
1
2
3
>>> from autoapi.models import ProjectInfo
>>> ProjectInfo.objects.all()
<QuerySet []>
2.Django管理页面

Django提供的管理网站(admin site)让你能够轻松地处理模型。网站的管理员可使用管理网站,但普通用户不能使用

  • 首先需要创建一个超级管理的账户
1
(django) ➜  AutoPlatform python manage.py createsuperuser

这里的username设置为admin, 密码也设置为admin

1
2
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
3.查看Django管理页面
  • 启动服务
1
2
3
4
5
6
7
8
9
(django) ➜  AutoPlatform python manage.py runserver 
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
August 25, 2020 - 15:12:38
Django version 3.1, using settings 'AutoPlatform.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
4. 进入到管理站点页面
  • 输入用户名和密码,进入到管理后台
5.管理后台页面加入应用

我们创建的模型,必须手工进行注册

  • 打开admin.py文件
1
2
3
4
5
6
from django.contrib import admin
from .models import ProjectInfo

# Register your models here.

admin.site.register(ProjectInfo)
  • 再打开管理后台页面可见

  • 来尝试着添加一条项目数据

  • 点击保存

  • 再进入到Django shell中查看
1
2
3
4
5
6
7
8
9
(django) ➜  AutoPlatform python manage.py shell
Python 3.7.5 (default, Nov 29 2019, 14:32:46)
[Clang 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from autoapi.models import ProjectInfo
>>> ProjectInfo.objects.all()
<QuerySet [<ProjectInfo: 接口自动化>]>
>>>

本文首发公众号: 伊洛的小屋,欢迎关注并查看更多内容!!!

和上面最开始相比,已经有了数据