I.はじめに
使用してウェブサイトの最近の開発、Python2.7+Django
BAEの発行時点で、データベースは異常があらわれた、ので、BAE
提供されたデータベースの自由な基本的なバージョン、データベースフィールドを挿入することができないキーワードが含まれているが、それはを使用して思い付いROT13
アルゴリズムの後に道のデータベースに追加されたフィールドの内容を変換します。
第二に、テキスト
-
達成するためにROT13アルゴリズム
ROT13
特別なアルゴリズム、暗号化と復号化アルゴリズムは同じです。あなたが他の暗号アルゴリズムを置き換えたい場合は、暗号化と復号化の区別に注意してください。ROT13 = string.maketrans(\ "ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz",\ "NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm") def rot13_encode(text): return string.translate(text, ROT13)
-
オブジェクト(新規クラス)
自動暗号化と復号化機能は、新しいクラスの基本的な理解を持っている必要があります。
新しいクラスがされpython2.2
たバージョンで導入され、すべての新しいクラスはすべてのオブジェクトクラスから継承します。
なぜ、新しいクラス、それを導入?公式の説明は次のとおりです。クラス統一するために
(class)
及び種類を(type)
。興味が自分自身のあなたのお母さんを頼むことができるならば、私たちの関係今日の内容は、あまりないです。
私たちは、新しいクラスが追加されている知っている必要があります__getattribute__
し、__setattr__
方法。たびにクラス属性へのアクセスの新しいインスタンスは、呼び出される
__getattribute__
メソッド。
そして、により__setattr__
プログラムが文字列関数の動的特性の一例を設定することにより、実行したときの方法、私たちは非常に我々の開発を促進し、達成することができます。getAttribute
#coding=utf-8 class A(object): #类A继承自object,是一个新式类 def __init__(self, id=100): self.id = id a = A() print a.id output: 100 print a.__getattribute__('id') #等价于a.id #output: 100
私たちは、__getattribute__書き換えしよう
#coding=utf-8 class A(object): #类A继承自object,是一个新式类 def __init__(self, id=100): self.id = id def __getattribute__(self, attr): #注意:我们使用A父类的__getattribute__方法获取属性 #如果直接使用getattr(self, attr)获取attr属性会造成死循环 #有兴趣可以尝试一下 return object.__getattribute__(self, attr) + 10 a = A() print a.id #output: 110 print object.__getattribute__(a, 'id') #output: 100
私たちは、プロパティへのアクセスを見ることができ
id
、呼び出しa
の__getattribute__
方法は、得られた値が扱われ、object.__getattribute__
方法は、実際のコンテンツを取得(これらの2つの方法とそれらの特性は、我々が使用する一方ことを心に留めておきますこれらの2つの方法)この記事の中核的なコンテンツです。
SETATTR
が__getattribute__
主人公が、あまり__setattr__
私達の機能を完了することができるが、しかし、非常に面倒になります。#coding=utf-8 class A(object): def __init__(self, id = 100): self.id = id a = A() print a.id #output: 100 a.__setattr__('id', 120) print a.id #output: 120
さて、あなたは、__getattribute__と__setattr__方法を使用する方法を学ぶ場合に劇場にも、次のエントリに私たちの準備作業。
あなたは、データベースのフィールドが自動的に暗号化されて挿入すると
書き換えられているモデルで保存する機能models.pyで保存するとき、我々は自動的に起動することができROT13
アルゴリズム変換機能を。
するにはArticle
、例としてモデル化します。#coding=utf-8 from django.db import models #实现ROT13算法 #当然,真正开发时该算法肯定不会写在models.py里 #这里为了简化代码,直接写在了这里 ROT13 = string.maketrans(\ "ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz",\ "NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm") def rot13_encode(text): return string.translate(text, ROT13) class Article(models.Model, object): #以下为最初的字段(仅挑选出了相关字段) title = models.CharField(max_length=200) content = models.TextField() hot = models.IntegerField(default=0) #文章的热度,此字段无需加密 #使用以下字段记录相关字段是否是加密状态 #使用"{name}_en"的方式命名,便于操作 title_en = models.BooleanField(default=False) content_en = models.BooleanField(default=False) #encrypt_items记录哪些字段需要加密 encrypt_items = ['content', 'title'] #重写Model的save函数,实现当向数据库插入字段时自动加密的功能 def save(self, *args, **kwargs): for attr in self.encrypt_items: if not getattr(self, '%s_en' % attr): self.__setattr__(attr, rot13_encode(getattr(self, attr))) self.__setattr__('%s_en' % attr, True) #调用父类Model的save函数,进行真正的数据库插入操作 super(Article, self).save(*args, **kwargs)
自動的にデータベースから読み取る解読
節約機能の欠如が上書き
:私たちは、データベースの内容は次のように書き込まれます読んだときに一般的に使用されていますart = Article.object.get(id=1) title = art.title content = art.content
しかし、前のセクションで、書き換えられた
save
データベースの内容を読み込むときに、後に、私たちは、記述する必要があります。art = Article.object.get(id=1) title = rot13_encode(art.title) content = rot13_encode(art.content)
この場合、ワークロードは、コードを書くために急増すると、他のコードが書かれている場合、それが線でのコード行を変更する必要があります-非常に苦痛な作業。だから我々はする必要が
Article
改善します。
達成するためにデータベースから読み込まれたときに自動的に復号化#coding=utf-8 from django.db import models #实现ROT13算法 ROT13 = string.maketrans(\ "ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz",\ "NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm") def rot13_encode(text): return string.translate(text, ROT13) #简化函数名称,便于调用 OGA = object.__getattribute__ REP = rot13_encode class Article(models.Model, object): title = models.CharField(max_length=200) content = models.TextField() hot = models.IntegerField(default=0) #文章的热度,此字段无需加密 title_en = models.BooleanField(default=False) content_en = models.BooleanField(default=False) #encrypt_items记录哪些字段需要加密 encrypt_items = ['content', 'title'] def __getattribute__(self, attr): try: if (attr in OGA(self, 'encrypt_items')) and OGA(self, '%s_en' % attr): #若所查询属性(字段)需要加密且已经被加密,解密后再返回 return REP(OGA(self, attr)) else: #所查询属性无需加密或未被加密,直接返回 return OGA(self, attr) except AttributeError as err: #可能出现AttributeError异常,捕获后直接上抛即可 raise err #重写Model的save函数,实现当向数据库插入字段时自动加密的功能 def save(self, *args, **kwargs): for attr in self.encrypt_items: if not OGA(self, '%s_en' % attr): #注意:这里注释掉了进行加密的这行代码。只有这样才能正常加密!!! #请往下阅读,我会说明原因 #self.__setattr__(attr, REP(OGA(self, attr))) self.__setattr__('%s_en' % attr, True) #调用Model的save函数 super(Article, self).save(*args, **kwargs)
コード行は、実際の暗号化を削除し、適切に機能するためにそれを暗号化するために、なぜ一部の読者は不思議に思うかもしれませんか?(間違いなく、それから、この記事が終了した、歩行賛美聖歌〜のポイントは)
私が(!がらくた)コード行を削除しません。この第一の特徴を実現した、しかし、データベースは、私がテストしたときに暗号化する必要があることを見つけたときフィールドしかし、暗号化されていないtitle_en
、とcontent_en
の値が1である(データベース1の代わりにTrue
、0False
)。
自然に問題をデバッグするために、私は少しにコードの最後の数行を変更しました:print OGA(self, 'title') super(Article, self).save(*args, **kwargs) print OGA(self, 'title')
これは、コールで
Model
のsave
印刷タイトルコールで見つかった真の価値ある旧機能save
の前に、title
それは通常、(私は、コードの行をコメントアウトしていないことに注意してください)暗号化されています。しかし、非常に興味深い節約するために呼び出した後、タイトルの真の価値は、それが非暗号化された値です。
コードの行の後にコメントアウトは、データベース内の値が暗号化されている場合。この点で、私は推測する(はい、推測)を呼び出しているsave
関数で、Django
次のようなコードを使用します:self.title = self.title
はい、あなたは正しい読み、それはそれだ、あなたが知っている、我々が持っている方法が書き換えられている、元のタイトルは暗号化されますが、一度一度使用され、それがタイトルを復号化されます、このようにして、データベースに挿入フィールドが解読されることです。
Article
__getattribute__
self.title = self.title
著者:LucianoSimonの
リンク:https://www.jianshu.com/p/193fd76e7a96
出典:ジェーン・ブック
著者によって予約ジェーン帳の著作権は、いかなる形で再現され、承認を得るために、作者に連絡して、ソースを明記してください。