锘??xml version="1.0" encoding="utf-8" standalone="yes"?>
涓嶆墦綆椾粠py鐨勮娉曞熀紜璇磋搗浜?鐩存帴璇磋瀵筪jango鐨勫績寰?
鎺ヨЕdjango棣栧厛闇瑕佷簡瑙e彲鑳藉氨鏄粬閭d釜model錛屽緩绔嬩竴涓猰odel灝變粈涔堥兘鏈変簡錛岃繖瀵逛簬鎼瀓ava寰椾漢鍛樻潵璇磋繕鏄尯鏈夊惛寮曞姏鐨勶紙褰撶劧璨屼技瀵逛簬鍔ㄦ佽璦榪欓兘鏄皬鍎跨錛夛紝閭d箞璁╂垜浠厛鐪嬩竴涓猰odel鐨勪緥瀛愶細
鍋鋒噿浜嗭紝鐩存帴鎷縟jango-admin閲岄潰鐨刄ser鍑烘潵浜?/p>
class User(models.Model): username = models.CharField(_('username'), maxlength=30, unique=True, validator_list=[validators.isAlphaNumeric])) first_name = models.CharField(_('first name'), maxlength=30, blank=True) last_name = models.CharField(_('last name'), maxlength=30, blank=True) email = models.EmailField(_('e-mail address'), blank=True) password = models.CharField(_('password'), maxlength=128)) class Meta: ordering = ('username',)
姣忎釜灞炴у氨鏄竴涓簱琛ㄧ殑瀛楁錛屽畾涔夎搗鏉ラ潪甯哥畝鍗曟槑浜嗭紝models閲岄潰鎻愪緵浜嗗緢澶氱綾葷殑Field綾諱技涓婇潰鐨凟mailField銆備笉鍚岀殑Field鏈変笉鍚岀殑璁劇疆錛屽彲浠ョ湅鐩稿簲鐨勫師鏉ユ潵浜嗚В鐩稿叧鐨勮緗紟
鍦╩odel class鍐呴儴榪樻湁涓涓猚lass Meta錛岃繖涓狢lass鐨勫睘鎬у埗瀹氫簡榪欎釜琛ㄧ殑涓浜涘瓨鍙栫瓥鐣ワ紝渚嬪榪欓噷鐨刼rdering銆侻etaClass閲岄潰鐨勫睘鎬у彲浠ョ敤model鐨刜meta灞炴у彇寰椼侽K錛岄偅涔堣繖鏍蜂竴涓猰odel鎬庝箞灝辮兘瀹炵幇瀵規暟鎹簱琛ㄧ殑鐏墊椿鎿嶄綔浜嗗憿銆傝鎴戜滑鏉ョ湅鐪嬪惂銆?/p>
棣栧厛鍏堝垎鏋愪竴涓?django/django/db/models/base.py榪欎釜鏂囦歡錛屽叾涓寘鍚簡models.Model榪欑被鐨勫畾涔夛細
鐪嬬湅class瀹氫箟鐨勭涓琛屽惂錛岀涓琛屽氨澶熸垜鐞㈢(涓闃靛瓙鐨勪簡錛?/p>
class Model(object): __metaclass__ = ModelBase
Model閲囩敤浜唍ew style class瀹氫箟錛屽叧浜庤繖涓唴瀹瑰ぇ瀹跺彲浠ユ斁鐙楃湅涓涓嬶紝絎竴琛屾槸涓涓猒_metaclass__灞炴х殑瀹氫箟錛岃灞炴х殑鍊兼槸ModelBase錛岃繖鏄竴涓被銆俖_metaclass__鐨勬剰鎬濇槸錛屾寚瀹氫竴涓猚lass錛岃繖涓猚lass鐨勫疄渚嬪氨鏄湰class錛岀浉淇℃偍宸茬粡鏅曚簡銆傞偅涔堝氨鎷胯繖涓狹odel鐨勪緥瀛愭潵璇存槑涓涓嬶紝濡傛灉娌℃湁__metaclass__榪欎釜灞炴э紝浜х敓涓涓疄渚嬪氨鏄甯哥殑嫻佺▼錛屾湁浜嗚繖涓睘鎬ф祦紼嬩細鏈夋敼鍙橈細
棣栧厛璋冪敤BaseModel.__new__(cls, name, bases, attrs)榪欎釜鏂規硶錛屽洖榪斿洖鐨勫兼槸涓涓猚lass綾誨瀷錛岀劧鍚庣敤榪欎釜class鏉ュ垱寤哄疄渚嬨傚叾瀹濨aseModel灝辨槸Model鐨勫厓綾伙紝鏉ュ埗瀹歁odel榪欎釜綾葷殑鏈緇堟牱瀛愩傚叧浜庡厓綾葷殑鏇村淇℃伅璇風湅榪欓噷
閭d箞鎴戜滑鐨勭洰鍏変竴涓嬭漿縐誨埌BaseModel榪欎釜綾諱笂錛屾垜鏈夌鐩磋錛孧eta榪欎釜class鏈鍚庡彲浠ョ敤_meta鏉ュ彇灝辨槸鍦ㄨ繖閲屽仛鐨勬墜鑴氾紝鐪嬩竴涓婤aseModel鐨勫畾涔夊惂錛屾湁鐐歸暱錛?/p>
class ModelBase(type): "Metaclass for all models" def __new__(cls, name, bases, attrs): # If this isn't a subclass of Model, don't do anything special.
if name == 'Model' or not filter(lambda b: issubclass(b, Model), bases): #1 return super(ModelBase, cls).__new__(cls, name, bases, attrs) # Create the class.
new_class = type.__new__(cls, name, bases, {'__module__': attrs.pop('__module__')}) #2
new_class.add_to_class('_meta', Options(attrs.pop('Meta', None))) #3
new_class.add_to_class('DoesNotExist', types.ClassType('DoesNotExist', (ObjectDoesNotExist,), {})) # Build complete list of parents #4 for base in bases: # TODO: Checking for the presence of '_meta' is hackish. if '_meta' in dir(base): new_class._meta.parents.append(base) new_class._meta.parents.extend(base._meta.parents) model_module = sys.modules[new_class.__module__] if getattr(new_class._meta, 'app_label', None) is None: # Figure out the app_label by looking one level up. # For 'django.contrib.sites.models', this would be 'sites'. new_class._meta.app_label = model_module.__name__.split('.')[-2] #5 # Bail out early if we have already created this class. m = get_model(new_class._meta.app_label, name, False) #6 if m is not None: return m # Add all attributes to the class. for obj_name, obj in attrs.items(): new_class.add_to_class(obj_name, obj) #7 # Add Fields inherited from parents for parent in new_class._meta.parents: for field in parent._meta.fields: # Only add parent fields if they aren't defined for this class. try: new_class._meta.get_field(field.name) except FieldDoesNotExist: field.contribute_to_class(new_class, field.name) #8 new_class._prepare() register_models(new_class._meta.app_label, new_class) #9 # Because of the way imports happen (recursively), we may or may not be # the first class for this model to register with the framework. There # should only be one class for each model, so we must always return the # registered version. return get_model(new_class._meta.app_label, name, False) #10
綆鍗曞垎鏋愪竴涓嬭繖涓唬鐮侊細
1. 媯鏌lass鏄惁涓篗odel鐨勫瓙綾伙紝涓嶆槸鐨勮瘽錛屼笉鍋氫換浣曞鐞嗭紝鐩存帴浼犵粰鐖剁被澶勭悊錛屼篃灝辯浉褰撲簬姝e父鐨勫鐞嗕簡class錛屾敞鎰弒uper鍦ㄥ閲嶇戶鎵跨殑鏃跺欏簲璇ヤ弗鏍間嬌鐢?
2. 鐢╰ype鏉ュ垱寤虹被錛屽垱寤虹殑灝辨槸姝e父鐨凪odelClass
3. 榪欏彞寰堥噸瑕侊紝add_to_class鏄疢odel閲岄潰鐨刢lass鏂規硶錛岃繖涓柟娉曞叾瀹炲氨鏄紶鍏ame鍜寁alue錛岀粰Model娣誨姞class灞炴?鐪嬪埌浜嗭紝鍘熸潵紲炲鐨刜meta灝辨槸榪欎箞鏉ョ殑. 鎻愬埌add_to_class鏂規硶錛岀畝鍗曠湅涓涓嬪畠鐨勪唬鐮侊細
def add_to_class(cls, name, value): if name == 'Admin': assert type(value) == types.ClassType, "%r attribute of %s model must be a class, not a %s object" % (name, cls.__name__, type(value)) value = AdminOptions(**dict([(k, v) for k, v in value.__dict__.items() if not k.startswith('_')])) if hasattr(value, 'contribute_to_class'): value.contribute_to_class(cls, name) else: setattr(cls, name, value) add_to_class = classmethod(add_to_class)
4. Meta鐨勯泦鎴愶紝Option鐨勮繖涓被鎻愪緵緇ф壙鏂規硶
5. 鍙栧緱applabel錛屽氨鏄妸model鐨勫悕瀛楀垎鍓插彇鍒版暟絎簩涓紝鎴戝緢鍠滄-2榪欐牱鐨勮瀹?/p>
6. get_model鏂規硶鍙栧緱緙撳瓨閲岄潰鐨勪笢瑗褲?/p>
7. 鎶婃墍鏈夌殑class attr鎷垮嚭鏉ユ悶涓閬嶏紝涓鑸殑灞炴у氨setattr寮勫洖鍘諱簡錛岃鏄繖涓睘鎬ф湁contribute_to_class榪欎釜callable灞炴э紝閭e氨鎵ц涔嬶紙Admin鐨勫鐞嗗畬鍏ㄤ篃鍙互榪欐牱錛屽叾瀹炴垜浠父鐢ㄧ殑objects灝辨槸鐢ㄨ繖涓柟娉曞紕鐨勶級
8. 姣忎釜Field璋冪敤鑷繁鐨刢ontribute_to_class鏂規硶鏉ヨ繘琛岀壒孌婄殑澶勭悊
9. 榪涘叆緙撳瓨錛岋紝鏆備笖鍙紦瀛樺惂錛岄噷闈㈢殑涓滆タ澶у鐪嬬湅寰堢畝鍗?鏂囦歡鍦?/django/django/db/models/loading.py 閲岄潰榪樻槸鏈夊緢澶氬唴瀹圭殑
10.鐪嬫敞閲婅鐨勫緢娓呮浜嗭紝鎴戜滑涓瀹氳鍦ㄧ紦瀛橀噷闈㈡嬁model銆?/p>
鍏朵腑闇瑕佹寚鍑虹殑鏄紝new_class._prepare() 榪欎釜鏂規硶錛岀畝鍗曞垪鍑虹墖孌碉細
def _prepare(cls):
# Creates some methods once self._meta has been populated.
opts = cls._meta
opts._prepare(cls)
錛庯紟錛庯紟
dispatcher.send(signal=signals.class_prepared, sender=cls)
涓棿鐪佺暐浜嗕竴浜涗唬鐮侊紝涓嶆槸鎴戞病鐪嬫噦鐨勫氨鏄病鎰忔濈殑錛屽叧閿鐪嬭繖涓猟ispatcher鍛銆傝繖閲屾槸鐩戝惉鑰呮ā寮忥紝dispatcher.send(signal=signals.class_prepared, sender=cls)鏀炬澗浜嗕竴涓寘鍚壒瀹氫俊鍙風殑浜嬩歡錛岃鐩戝惉鐨勪漢鍙互鍋氱浉搴旂殑澶勭悊銆傝繖鏍風殑淇″彿榪樻湁寰堝縐嶏紝鎴戜滑鍙互寰堢畝鍗曠殑鎴幏淇″彿錛屽鐞嗙浉搴旂殑鍐呭銆備篃璁告偍榪樿寰楋紝鍦ㄦ垜浠垱寤篸b鐨勬椂鍊欙紝浼氭彁紺哄垱寤轟竴涓秴綰х敤鎴鳳紝鍏跺疄灝辨槸鐢ㄨ繖涓柟娉曟潵寮勭殑銆?/p>
閭f垜涓轟粈涔堣鎶婅繖涓崟鐙嬁鍑烘潵璇村憿錛屽洜涓虹洃鍚繖涓簨浠剁殑浜轟笉鏄埆浜猴紝鏄?objects"錛侊紒錛佸湪鏂囦歡/django/django/db/models/manager.py鐨勫紑澶村氨鏈夎繖鏍風殑浠g爜錛?/p>
def ensure_default_manager(sender): cls = sender if not hasattr(cls, '_default_manager'): # Create the default manager, if needed. try: cls._meta.get_field('objects') raise ValueError, "Model %s must specify a custom Manager, because it has a field named 'objects'" % cls.__name__ except FieldDoesNotExist: pass cls.add_to_class('objects', Manager()) dispatcher.connect(ensure_default_manager, signal=signals.class_prepared)
瀹氫箟浜嗕竴涓猚allable錛岀劧鍚庣洃鍚瑂ignals.class_prepared淇″彿錛屽懙鍛碉紝榪炰笂浜嗗惂錛屽彧瑕丆lass鍑嗗濂戒簡錛屽氨璋冪敤榪欎釜鏂規硶銆傜畝鍗曞垽鏂湁娌℃湁_default_manager'灞炴у拰meta閲岄潰鐨刼bjects鍚庯紝寮濮嬫彃鍏bjects銆俢ls.add_to_class('objects', Manager()) 寰堢啛鎮夊惂錛屽墠闈㈣榪囦笉澶氳浜嗐?/p>
PS錛氬啓鍒拌繖閲屼笉鐢卞緱鎰熷徆錛屼負鍟ュ悓鏍鋒槸寰Class閲岄潰鍔犲叆涓滀笢錛岃鎼炶繖涔堝鐨勮姳鏍峰憿錛屾垜浠ュ墠涔熷啓榪囦竴涓猂ails閰嶇疆鍔犺澆榪囩▼鐨?a href="http://www.tkk7.com/sshwsfc/archive/2006/11/20/82401.html" target="_blank">鍒嗘瀽鏂囨。錛岃櫧鐒朵竴涓畝鍗曠殑鍔犺澆閰嶇疆灝辨妸鎵鏈夊姩鎬佽璦鐜╀釜閬嶏紝浣嗘槸榪欎篃澶笉瑙勮寖浜嗗惂錛屽彲鑳戒笉榪欎箞鐜╁氨涓嶇畻“鍔ㄦ?#8221;璇█浜嗗惂錛屽搱鍝堛?/p>
緇堜簬Model鐨凜lass閫犲ソ浜嗭紝鐩鎬俊澶у浠ュ悗閫犺嚜宸辯殑Class涔熻兘鐜╁嚭鏇村鐨勮姳鏍楓傞偅涔堝彲浠ュ紑濮嬩笅涓姝ヤ簡銆傛垜鍒拌佸鍚庡啀鍐欏惂錛屾墦綆楄璁茬濂囩殑objects錛屼篃灝辨槸Manager錛屽叾瀹炲氨鏄帺QuerySet銆傘傞偅閲屾湁寰堝鐨刜_xxx__鏂規硶錛屽緢濂藉緢寮哄ぇ