一、CRM项目(1)

  引入三个表:用户表,客户表,校区表,班级表,梳理逻辑关系并迁移数据库,生成表。

  使用admin插入数据,admin是Django提供的web形式的后台数据管理页面,它是和用户认证组件相通的,使用超级用户即可登录admin后台,并管理自己的数据库。

  做出全部客户列表页面和我的客户列表页面。

二、装饰器

  在python中,装饰器以及前面讲到的迭代器,生成器都是十二分重要的高级函数。要想理解装饰器,首先要掌握以下几点准备知识:

1、准备一:回顾并理解作用域的相关知识

2、准备二:函数即对象

    在python的世界里,函数和我们之前的[1,2,3],'abc',8等一样都是对象,而且函数是最高级的对象(对象是类的实例化,可以调用相应的方法,函数是包含变量对象的对象)

  1. def foo():
  2.   print('i am the foo')
  3.   bar()
  4.  
  5.   def bar():
  6.   print('i am the bar')
  7.  
  8.   foo()
  9.   # def bar(): # bar函数定义放到foo()后边会报错
  10.   # print('i am the bar')

带着上面的问题,我们看看函数在内存的存储情况,如下图:

    既然函数是对象,那么自然满足下面两个条件:函数对象的调用仅仅比其他对象多了一个()而已!foo,bar与a,b一样都是个变量名。那么上面示例的报错问题也就解决了,因为只有函数加载到内存才可以被调用。

    1)函数可以被赋给其他变量

  1. def foo():
  2.   print('foo')
  3.   bar=foo
  4.   bar()
  5.   foo()
  6.   print(id(foo),id(bar)) #4321123592 4321123592

    2)函数可以被定义在另外一个函数内(作为参数&作为返回值),类似于整型,字符串等对象

  1. #*******函数名作为参数**********
  2.   def foo(func):
  3.    print('foo')
  4.    func()
  5.  
  6.   def bar():
  7.    print('bar')
  8.  
  9.   foo(bar)
  10.  
  11.   #*******函数名作为返回值*********
  12.   def foo():
  13.    print('foo')
  14.    return bar
  15.  
  16.   def bar():
  17.    print('bar')
  18.  
  19.   b=foo()
  20.   b()

   注意:这里说的函数都是指函数名,比如foo;而foo()表示已经执行函数了,foo()是什么类型取决于return的内容是什么类型!!!另外,如果你理解不了对象,那么就将函数理解成变量,因为函数对象总会由一个或多个变量引用,比如foo,bar。

3、准备三:函数的嵌套以及闭包

    python允许创建嵌套函数,通过在函数内部def的关键字再声明一个函数即为嵌套。先看下面这个函数嵌套的示例,分析能否正常执行:

  1. def foo():
  2.   print('foo')
  3.    def bar():
  4.    print('bar')
  5.   # bar()
  6.   bar() # 报错原因:找不到这个引用变量
  7.   # 分析:没错,bar就是一个变量名,有自己的作用域的,因此bar()不能执行。

  再看下面一个函数嵌套的示例,并思考执行inner函数的两种方法有什么区别:

  1. def outer():
  2.     x = 1
  3.     def inner():
  4.       print (x)
  5.     # inner() # 方式一
  6.     return inner # 方式二
  7.  
  8.   # outer() # 方式一
  9.   in_func=outer() # 方式二:这里其实就是一个变量赋值,将inner的引用对象赋值给in_func,类似于a=5,b=a一样
  10.   in_func()

   分析:两种调用方式有区别吗,不都是在外面调用inner吗?按照方式二调用后,inner()已经加载到内存了!

    回顾闭包的概念:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)。

    如上示例,inner就是内部函数,inner里引用了外部作用域的变量x(x在外部作用域outer里面,不是全局作用域),则这个内部函数inner就是一个闭包。

4、装饰器的概念

    说了这么多,终于到装饰器了。装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

    比如,业务生产中有如下一个大量调用的函数:

  1.  def add():
  2.    for i in range(30000000):
  3.   ret+=i
  4.    print(ret)
  5.   add()

现在有一个新的需求,希望可以记录下函数的执行时间,于是在函数中添加日志代码:

  总结:虽然实现了需求,但是这样做违反了开发的开放封闭原则的封闭原则,即不要轻易去改已经写好方法!而且如果要给其他函数也要加记录时间的代码,再用以上方法会造成代码冗余,所以想一想有没有其他方法。你可能会想到单独定义一个记录时间的函数,如下:

  1. import time
  2.   def show_time(func):
  3.   start_time=time.time()
  4.   func()
  5.   end_time=time.time()
  6.    print('spend %s'%(end_time-start_time))
  7.  
  8.   def add():
  9.    for i in range(30000000):
  10.   ret+=i
  11.    print(ret)
  12.  
  13.   show_time(add)

上面示例从逻辑上不难理解,而且运行正常。但是这样的话,之前执行业务逻辑时,执行运行add(),但是现在不得不改成show_time(add),这种方式就违反了开发的开放封闭原则的开放原则,即不要改动之前已有的调用方式。那么有没有更好的方式的呢?当然有,答案就是装饰器。 

5、简单装饰器

    如果,可以将上例中的add()=show_time(add),那么就可以在不违反开放封闭原则前提下完成需求了,所以,我们需要show_time(add)返回一个函数对象,而这个函数对象内则是核心业务函数:执行func()与装饰函数时间计算,修改如下:

  1. import time
  2.  
  3.   def show_time(func):
  4. def inner():
  5. start_time=time.time()
  6. func()
  7. end_time=time.time()
  8. print('spend %s'%(end_time-start_time))
  9. return inner
  10.  
  11.   def add():
  12. for i in range(30000000):
  13. ret+=i
  14. print(ret)
  15.  
  16.   add=show_time(add)
  17.   add()

    分析:函数show_time就是装饰器,它把真正的业务方法func包裹在函数里面,看起来像add被上下时间函数装饰了。在这个例子中,函数进入和退出时 ,被称为一个横切面(Aspect),这种编程方式被称为面向切面的编程(Aspect-Oriented Programming)。

    @符号是装饰器的语法糖,在定义函数的时候使用,避免再一次赋值操作,如下示例:

  1. import time
  2.  
  3.   def show_time(func):
  4.    def inner():
  5.    start_time=time.time()
  6.    func()
  7.   end_time=time.time()
  8.   print('spend %s'%(end_time-start_time))
  9.  
  10.    return inner
  11.   
  12.   @show_time # add=show_time(add)
  13.   def add():
  14. for i in range(30000000):
  15. ret+=i
  16. print(ret)
  17.  
  18.   @show_time # bar=show_time(bar)
  19.   def bar():
  20.    print('in the bar')
  21.    time.sleep(2)
  22.  
  23.   add()
  24.   bar()

 如上所示,这样我们就可以省去add = show_time(add)这一句了,直接调用add()即可得到想要的结果。如果我们有其他的类似函数,我们可以继续调用装饰器来修饰函数,而不用重复修改函数或者增加新的封装。这样,我们就提高了程序的可重复利用性,并增加了程序的可读性。

    这里需要注意:add=show_time(add)其实是把inner引用的对象引用给了add,而inner里的变量func之所以可以用,就是因为inner是一个闭包函数。

    @show_time帮我们做的事情就是当我们执行业务逻辑foo()时,执行的代码由粉框部分转到蓝框部分,仅此而已!装饰器在Python使用如此方便都要归因于Python的函数能像普通的对象一样能作为参数传递给其他函数,可以被赋值给其他变量,可以作为返回值,可以被定义在另外一个函数内。    

6、带参数的被装饰函数

  1. import time
  2.  
  3.   def show_time(func):
  4.    def inner(a,b):
  5.    start_time=time.time()
  6.    func(a,b)
  7.    end_time=time.time()
  8.   print('spend %s'%(end_time-start_time))
  9.  
  10.    return inner
  11.  
  12.   @show_time # add=show_time(add)
  13.   def add(a,b):
  14.   time.sleep(1)
  15.   print(a+b)
  16.  
  17.   add(2,4)

7、注意点:当被装饰函数有返回值的情况

  1. import time
  2.  
  3.   def show_time(func):
  4.    def inner(a,b):
  5.    start_time=time.time()
  6.   ret=func(a,b)
  7.    end_time=time.time()
  8.   print('spend %s'%(end_time-start_time))
  9.   return ret # 若被装饰函数有返回值,则inner函数也一定要返回func(a,b)的结果
  10.  
  11.    return inner
  12.  
  13.   @show_time # add=show_time(add)
  14.   def add(a,b):
  15.   time.sleep(1)
  16.   return a+b
  17.  
  18.   print(add(2,5))

8、装饰器在登录认证方面的应用:

Django为我们提供了一个装饰器函数login_required,当我们只想限制少量页面登录才能访问时,就可以使用装饰器函数,而没有必要加中间件。

三、补充

1、使用django的admin页面录入数据

  1)首先,在admin.py中配置如下信息:

  1. from django.contrib import admin
  2.   # Register your models here.
  3.   from app01.models import * # 将models模块中的所有类(表)引入
  4.  
  5.   admin.site.register(UserInfo) # 括号中是model中的类(表),下面也如此
  6.   admin.site.register(Customer)
  7.   admin.site.register(Campuses)
  8.   admin.site.register(ClassList)

  2)创建超级用户

  1.  python manage.py createsuperuser

  3)以超级用户登录admin后台,开始录入数据

2、安装multiselectfield

  方式一:

  1.   pip3 install multiselectfield

  方式二:pycharm软件上按如下操作

    file -> settints -> Project:xxx -> Project Interpreter -> 右侧绿色加号 -> 搜索multiselectfield ->Install Package

  解释:我们之前学过gender=models.CharField(choices=(('male','男')('female','女'))),使用modelform会渲染成多个type为radio的input标签,model中定义course = MultiSelectField("咨询课程", choices=(('Linux', 'Linux中高级'),('PythonFullStack', 'Python高级全栈开发'),), blank=True, null=True),使用modelform会渲染成多个type为checkbox的input标签。

3、blank=True

  1.   qq_name = models.CharField('QQ昵称', max_length=64, blank=True, null=True)

  解释:null=True表示数据库中不能为空,blank=True表示使用modelform组件中校验该字段输入时不能为空,而只写null=True则不能校验。Django的admin也是基于modelform实现的,所以使用admin提交表单数据时,只写了null=True而没有写blank=True的则必须输入值,不能为空。

4、model中模型类的__str__方法必须返回字符串类型,不能返回其他类型。

5、location的search属性

  search 属性是一个可读可写的字符串,可设置或返回当前 URL 的查询部分(即问号 ? 之后的部分)。

6、javascript的slice()方法

  语法:string.slice(start,end)

  解释:提取字符串的某个部分,并以新的字符串返回被提取的部分,索引从0开始,顾头不顾尾。

Django-- CRM1客户建表与装饰器的更多相关文章

  1. 浅谈Django的中间件与Python的装饰器

    浅谈Django的中间件 与Python的装饰器 一.原理 1.装饰器是Python的一种语法应用,利用闭包的原理去更改一个函数的功能,即让一个函数执行之前先到另外一个函数中执行其他需求语句,在执行该 ...

  2. Django视图函数函数之视图装饰器

    FBV模式装饰器: 普通函数的装饰器(语法糖@) views.py from django.shortcuts import render def wrapper(f): def inner(*arg ...

  3. django的FBV和CBV的装饰器例子

    备忘 def auth(func): def inner(request,*args,**kwargs): u = request.COOKIES.get('username111') if not ...

  4. Django基础之给视图加装饰器

    1. 使用装饰器装饰FBV FBV本身就是一个函数,所以和给普通的函数加装饰器无差: def wrapper(func): def inner(*args, **kwargs): start_time ...

  5. Django使用models建表的一些另类功能

    当我们对某个表需要在创建时,给他绑定一个随机的id,那么我们怎么做呢? 当创建一个用户时执行的为save方法,所以通过下面的 super(UserInfo, self).save(*args, **k ...

  6. django使用mongodb建表

    1.安装mongodb的py模块包 pip install mongoengine 同时安装了mongoengine.pymongo 2.在项目配置文件settings.py中配置 from mong ...

  7. [oldboy-django][2深入django]FBV + CBV + 装饰器

    FBV django CBV & FBV - FBV function basic view a. urls 设置 urls(r'^test.html$', views.test) b. vi ...

  8. django view 装饰器

    Django提供了几个可以应用于视图以支持各种HTTP特性的装饰器 Allowed HTTP django.views.decorators.http里的装饰器可以根据请求方法限制对视图的访问. re ...

  9. django中视图函数中装饰器

    方法一 给指定方法加 from django.utils.decorators import method_decorator class xx(View): @method_decorator(装饰 ...

随机推荐

  1. LOJ2722 「NOI2018」情报中心

    「NOI2018」情报中心 题目描述 C 国和D 国近年来战火纷飞. 最近,C 国成功地渗透进入了D 国的一个城市.这个城市可以抽象成一张有$n$ 个节点,节点之间由$n - 1$ 条双向的边连接的无 ...

  2. tcpdump示例

    今天有需求要用tcpdump,给一个我使用的例子: sudo /usr/sbin/tcpdump  dst 10.20.137.24 and tcp port 8080 -A -s0  -w nous ...

  3. socket发送结构体

    struct send_info {char info_from[20]; //发送者IDchar info_to[20]; //接收者IDint info_length; //发送的消息主体的长度c ...

  4. [转]升级Flash Builder 4.6中的Flash Player版本

    Adobe自发布Flash Builder 4.6后,就暂停了Flash Builder新版本的发布.但AIR和FlashPlayer版本仍然保持不断的更新.在下载新的AIRSDK并覆盖到Flash ...

  5. POJ2785(upper_bound)

    #include"cstdio" #include"algorithm" using namespace std; ; int A[MAXN],B[MAXN], ...

  6. Linux keepalived与lvs的深入分析

    一)概述 在本篇文章里,我们会涉及两部份内容,一个是LVS,另一个则是keepalived. 即我们用LVS和keepalived实现了负载均衡及高可用的服务器.   LVS有实现三种IP负载均衡技术 ...

  7. nginx实现防盗链配置方法介绍

    有些朋友觉得防盗链就是防止图片,其实有很多东西要进行防盗链了,下面我来介绍在nginx中实现防盗链配置方法有对图片防盗链与下载资源等. 防盗链配置 假设网站域名是 www.php100.com. 编辑 ...

  8. JVM体系结构之二:类加载器之2:JVM 自定义的类加载器的实现和使用

    一.回顾一下jdk自带的类加载器: 1.java虚拟机自带的加载器     根类加载器(Bootstrap,c++实现)     扩展类加载器(Extension,java实现)     应用类加载器 ...

  9. django examples 学习笔记(1)创建一个独立的python环境

    pip install virtualenv   创建一个虚拟环境 virtualenv   my_env      创建一个独立的环境 source my_env/bin/activate   激活 ...

  10. 推荐!Html5精品效果源码分享

    一直在看别人的汇总,看到了一些不错的关于 HTML5内容的源码,我也汇总下分享出来,好东西需要共享!希望可以帮到需要的朋友. 1.劲爆分享:HTML5动感的火焰燃烧动画特效 这又是一款基于HTML5的 ...