您的位置:首页 > 编程语言 > Go语言

django 文档参考模型

2012-10-26 15:10 501 查看

def():


Modelreference

模型参考

Amodelisthesingle,definitivesourceofdataaboutyourdata.Itcontainstheessentialfieldsandbehaviorsofthedatayou'restoring.Generally,eachmodelmapstoasingledatabasetable.

Thebasics:

EachmodelisaPythonclassthatsubclassesdjango.db.models.Model.

Eachattributeofthemodelrepresentsadatabasefield.
Modelmetadata(non-fieldinformation)goesinaninnerclassnamed
Meta.
MetadatausedforDjango'sadminsitegoesintoaninnerclassnamed
Admin.
Withallofthis,Djangogivesyouanautomatically-generateddatabase-accessAPI,whichisexplainedinthe
DatabaseAPIreference.

Acompaniontothisdocumentisthe
officialrepositoryofmodelexamples.(IntheDjangosourcedistribution,theseexamplesareinthe
tests/modeltestsdirectory.)

Quickexample

ThisexamplemodeldefinesaPerson,whichhasa
first_nameand
last_name:

fromdjango.dbimportmodels

classPerson(models.Model):
first_name=models.CharField(maxlength=30)
last_name=models.CharField(maxlength=30)

first_nameand
last_namearefieldsofthemodel.Eachfieldisspecifiedasaclassattribute,andeachattributemapstoadatabasecolumn.

TheabovePersonmodelwouldcreateadatabasetablelikethis:

CREATETABLEmyapp_person(
"id"serialNOTNULLPRIMARYKEY,
"first_name"varchar(30)NOTNULL,
"last_name"varchar(30)NOTNULL
);

Sometechnicalnotes:

Thenameofthetable,myapp_person,isautomaticallyderivedfromsomemodelmetadatabutcanbeoverridden.See
Tablenamesbelow.

表名myapp_person从模型的元数据自动产生,但也可以被重写。

Anidfieldisaddedautomatically,butthisbehaviorcanbeoverriden.See

Automaticprimarykeyfieldsbelow.

id字段是自动附加的,也可以被重写。

TheCREATE
TABLESQLinthisexampleisformattedusingPostgreSQLsyntax,butit'sworthnotingDjangousesSQLtailoredtothedatabasebackendspecifiedinyour

settingsfile.

Fields

Themostimportantpartofamodel--andtheonlyrequiredpartofamodel--isthelistofdatabasefieldsitdefines.Fieldsarespecifiedbyclassattributes.

Example:


classMusician(models.Model):
first_name=models.CharField(maxlength=50)
last_name=models.CharField(maxlength=50)
instrument=models.CharField(maxlength=100)

classAlbum(models.Model):
artist=models.ForeignKey(Musician)#定义外键
name=models.CharField(maxlength=100)
release_date=models.DateField()#日期字段
num_stars=models.IntegerField()


Fieldnamerestrictions

Djangoplacesonlytworestrictionsonmodelfieldnames:

AfieldnamecannotbeaPythonreservedword,becausethatwouldresultinaPythonsyntaxerror.Forexample:

字段名不能是Python保留字。
classExample(models.Model):
pass=models.IntegerField()#'pass'isareservedword!


Afieldnamecannotcontainmorethanoneunderscoreinarow,duetothewayDjango'squerylookupsyntaxworks.Forexample:

字段名不能包含多于一个下划线。因为Django的query查找语法。
classExample(models.Model):
foo__bar=models.IntegerField()'foo__bar'hastwounderscores!


Theselimitationscanbeworkedaround,though,becauseyourfieldnamedoesn'tnecessarilyhavetomatchyourdatabasecolumnname.See

db_columnbelow.

SQLreservedwords,suchasjoin,
whereor
select,areallowedasmodelfieldnames,becauseDjangoescapesalldatabasetablenamesandcolumnnamesineveryunderlyingSQLquery.Itusesthequotingsyntaxofyourparticulardatabaseengine.

SQL保留字,如join,where,select,可以被用作模型的字段名。

Fieldtypes

Eachfieldinyourmodelshouldbeaninstanceoftheappropriate
Fieldclass.Djangousesthefieldclasstypestodetermineafewthings:

Thedatabasecolumntype(e.g.INTEGER,
VARCHAR).
ThewidgettouseinDjango'sadmininterface,ifyoucaretouseit(e.g.
<inputtype="text">,
<select>).
Theminimalvalidationrequirements,usedinDjango'sadminandinmanipulators.

Hereareallavailablefieldtypes:

AutoField

自增字段

AnIntegerFieldthatautomaticallyincrementsaccordingtoavailableIDs.Youusuallywon'tneedtousethisdirectly;aprimarykeyfieldwillautomaticallybeaddedtoyourmodelifyoudon'tspecify
otherwise.See
Automaticprimarykeyfields.

是自增的IntegerField.一般不需要直接操作它。如果除此之外未指定其他的字段为主键,则自增字段会被设置为主键。

BooleanField

布尔型字段

Atrue/falsefield.

Theadminrepresentsthisasacheckbox.

CharField

字符串型字段

Astringfield,forsmall-tolarge-sizedstrings.

Forlargeamountsoftext,useTextField.

大文本用TextField.

Theadminrepresentsthisasan<input
type="text">(asingle-lineinput).

CharFieldhasanextrarequiredargument,
maxlength,themaximumlength(incharacters)ofthefield.ThemaxlengthisenforcedatthedatabaselevelandinDjango'svalidation.

CharField的构造器需要额外提供maxlength参数,这是必须的。

CommaSeparatedIntegerField

逗号分割的整数字段

Afieldofintegersseparatedbycommas.AsinCharField,the
maxlengthargumentisrequired.

和CharField一样,必须向其构造器传递maxlength参数。

DateField

日期字段

Adatefield.Hasafewextraoptionalarguments:

ArgumentDescription
auto_nowAutomaticallysetthefieldtonoweverytimetheobjectissaved.Usefulfor"last-modified"timestamps.Notethatthecurrentdateis
alwaysused;it'snotjustadefaultvaluethatyoucanoverride.

当对象被保存时,自动设置为现在时间。可用于表示最后修改时间的时间戳。注意:当前日期总是会被使用,而不是仅仅一个默认值。
auto_now_addAutomaticallysetthefieldtonowwhentheobjectisfirstcreated.Usefulforcreationoftimestamps.Notethatthecurrentdateis
alwaysused;it'snotjustadefaultvaluethatyoucanoverride.

当对象被初次创建的时候,自动设置为现在时间。可用于表示创建时间的时间戳。注意:当前日期总是被使用,而不仅仅是一个默认值。
Theadminrepresentsthisasan<input
type="text">withaJavaScriptcalendarandashortcutfor"Today."

DateTimeField

时间日期字段

Adateandtimefield.Takesthesameextraoptionsas
DateField.

拥有和DateField一样的两个额外选项(auto_now,auto_now_add).

Theadminrepresentsthisastwo<input
type="text">fields,withJavaScriptshortcuts.

EmailField

ACharFieldthatchecksthatthevalueisavalide-mailaddress.Thisdoesn'taccept
maxlength.

能够验证是合法的email的CharField字段。不接受maxlength.

FileField

Afile-uploadfield.

文件上传字段

Hasanextrarequiredargument,upload_to,alocalfilesystempathtowhichfilesshouldbeupload.Thispathmaycontain

strftimeformatting,whichwillbereplacedbythedate/timeofthefileupload(sothatuploadedfilesdon'tfillupthegivendirectory).

有一个额外的参数,upload_to,表示一个本地文件路径,用于存放文件。此路径可以包含strftime格式化。

Theadminrepresentsthisasan<input
type="file">(afile-uploadwidget).

UsingaFileFieldoran
ImageField(seebelow)inamodeltakesafewsteps:

在模型中使用FileField或ImageField需要下列步骤:

Inyoursettingsfile,you'llneedtodefineMEDIA_ROOTasthefullpathtoadirectorywhereyou'dlikeDjangotostoreuploadedfiles.(Forperformance,thesefilesarenotstoredinthedatabase.)
DefineMEDIA_URLasthebasepublicURLofthatdirectory.MakesurethatthisdirectoryiswritablebytheWebserver'suseraccount.

在settings文件中,定义MEDIA_ROOT为保存上传文件的目录的全路径。
AddtheFileFieldor
ImageFieldtoyourmodel,makingsuretodefinethe
upload_tooptiontotellDjangotowhichsubdirectoryof
MEDIA_ROOTitshoulduploadfiles.

向模型中添加FileField或ImageField字段。设置upload_to选项,指示Django将文件上传到MEDIA_ROOT的哪个子目录中。
Allthatwillbestoredinyourdatabaseisapathtothefile(relativeto
MEDIA_ROOT).You'llmustlikelywanttousetheconvenience
get_<fieldname>_urlfunctionprovidedbyDjango.Forexample,ifyour
ImageFieldiscalled
mug_shot,youcangettheabsoluteURLtoyourimageinatemplatewith
{{object.get_mug_shot_url
}}.

存储于数据库中的是文件的相对路径(相对于目录MEDIA_ROOT).可利用get_<fieldname>_url函数。举例来说,如果ImageField字段名为mug_shot,则可以在模版中通过{{object.get_mug_shot_url}}字段获取图片的绝对路径。

FilePathField

文件路径字段

Afieldwhosechoicesarelimitedtothefilenamesinacertaindirectoryonthefilesystem.Hasthreespecialarguments,ofwhichthefirstisrequired:

该字段的值被限制为某个目录下的文件名。它有3个特殊参数,其中第一个参数是必要的。

ArgumentDescription
pathRequired.Theabsolutefilesystempathtoadirectoryfromwhichthis
FilePathFieldshouldgetitschoices.Example:
"/home/images".

必填。指向可选的文件名所在目录的名称。如:"/home/images".
matchOptional.Aregularexpression,asastring,that
FilePathFieldwillusetofilterfilenames.Notethattheregexwillbeappliedtothebasefilename,notthefullpath.Example:
"foo.*/.txt^",whichwillmatchafilecalled
foo23.txtbutnot
bar.txtorfoo23.gif.

可选。是一个正则表达式,FilePathField用来过滤文件名。该正则表达式用于文件名的base部分,而不是全名。如:"foo.*/.txt^",能够匹配foo23.txt而不能匹配bar.txt或foo23.gif.
recursiveOptional.EitherTrueor
False.Defaultis
False.Specifieswhetherallsubdirectoriesof
pathshouldbeincluded.

可选,默认值为False.表示path的子目录是否包括在内。
Ofcourse,theseargumentscanbeusedtogether.

Theonepotentialgotchaisthatmatchappliestothebasefilename,notthefullpath.So,thisexample:

注意:下列代码中

FilePathField(path="/home/images",match="foo.*",recursive=True)

...willmatch/home/images/foo.gifbutnot
/home/images/foo/bar.gifbecausethe
matchappliestothebasefilename(foo.gifand
bar.gif).

能匹配/home/images/foo.gif但不匹配/home/images/foo/bar.gif(因为匹配的是文件名的base部分)

FloatField

浮点数字段

Afloating-pointnumber.Hastworequiredarguments

有两个必须的字段:

ArgumentDescription
max_digitsThemaximumnumberofdigitsallowedinthenumber.

数字长度
decimal_placesThenumberofdecimalplacestostorewiththenumber.

十进制位的数目,即有效位数
Forexample,tostorenumbersupto999witharesolutionof2decimalplaces,you'duse:

models.FloatField(...,max_digits=5,decimal_places=2)

Andtostorenumbersuptoapproximatelyonebillionwitharesolutionof10decimalplaces:

models.FloatField(...,max_digits=19,decimal_places=10)

Theadminrepresentsthisasan<input
type="text">(asingle-lineinput).

ImageField

图片字段

LikeFileField,butvalidatesthattheuploadedobjectisavalidimage.Hastwoextraoptionalarguments,
height_fieldand
width_field,which,ifset,willbeauto-populatedwiththeheightandwidthoftheimageeachtimeamodelinstanceissaved.

类似于FileField,但会验证上传的对象是否为图片。有两个额外的可选字段:height_field和width_field

Requiresthe
PythonImagingLibrary.

IntegerField

整数字段

Aninteger.

Theadminrepresentsthisasan<input
type="text">(asingle-lineinput).

IPAddressField

IP地址字段

AnIPaddress,instringformat(i.e."24.124.1.30").

Theadminrepresentsthisasan<input
type="text">(asingle-lineinput).

NullBooleanField

允许为空的布尔型字段

LikeaBooleanField,butallows
NULLasoneoftheoptions.Usethisinsteadofa
BooleanFieldwith
null=True.

可以用这个字段类型代替设置了null=True属性的BooleanField.

Theadminrepresentsthisasa<select>boxwith"Unknown","Yes"and"No"choices.

PhoneNumberField

电话号码字段

ACharFieldthatchecksthatthevalueisavalidU.S.A.-stylephonenumber(intheformat
XXX-XXX-XXXX).

表示美国电话号码的格式的字段(xxx-xxx-xxxx)

PositiveIntegerField

正整数字段

LikeanIntegerField,butmustbepositive.

PositiveSmallIntegerField

小的正整数字段

LikeaPositiveIntegerField,butonlyallowsvaluesunderacertain(database-dependent)point.

最大值取决于具体的数据库特性

SlugField

"Slug"isanewspaperterm.Aslugisashortlabelforsomething,containingonlyletters,numbers,underscoresorhyphens.They'regenerallyusedinURLs.

"Slug"是报纸的术语。表示一个短的标签,仅包含字母,数字,下划线或连字符。一般用于URL中。

IntheDjangodevelopmentversion,youcanspecify
maxlength.Ifmaxlengthisnotspecified,Djangowilluseadefaultlengthof50.InpreviousDjangoversions,there'snowaytooverridethelengthof50.

在Django开发版中,可指定maxlength.默认的长度是50.在低版本的Django中,没有办法可以覆盖长度为50的限制。

Impliesdb_index=True.

隐含db_index=True

Acceptsanextraoption,prepopulate_from,whichisalistoffieldsfromwhichtoauto-populatetheslug,viaJavaScript,intheobject'sadminform:

接受一个额外选项prepopulate_from,用于指示在admin表单中的可选值。

models.SlugField(prepopulate_from=("pre_name","name"))

prepopulate_fromdoesn'tacceptDateTimeFields.

prepopulate_from不接受DateTimeField字段

TheadminrepresentsSlugFieldasan
<inputtype="text">(asingle-lineinput).

SmallIntegerField

小整数字段

LikeanIntegerField,butonlyallowsvaluesunderacertain(database-dependent)point.

TextField

大文本字段

Alargetextfield.

Theadminrepresentsthisasa<textarea>(amulti-lineinput).

TimeField

时间字段

Atime.Acceptsthesameauto-populationoptionsas
DateFieldandDateTimeField.

和DateField以及DateTimeField一样也有两个时间戳字段。

Theadminrepresentsthisasan<input
type="text">withsomeJavaScriptshortcuts.

URLField

AfieldforaURL.Iftheverify_existsoptionis
True(default),theURLgivenwillbecheckedforexistence(i.e.,theURLactuallyloadsanddoesn'tgivea404response).

表示URL的字段。如果verify_exists选项为True(默认),则会检查URL的可用性(比方说,URL能够加载,并且反馈404错误)。

Theadminrepresentsthisasan<input
type="text">(asingle-lineinput).

USStateField

两个字母表示的美国州名字段

Atwo-letterU.S.stateabbreviation.

Theadminrepresentsthisasan<input
type="text">(asingle-lineinput).

XMLField

XML字段

ATextFieldthatchecksthatthevalueisvalidXMLthatmatchesagivenschema.Takesonerequiredargument,
schema_path,whichisthefilesystempathtoa
RelaxNGschemaagainstwhichtovalidatethefield.

表示XML文档的TextField.会针对指定的schema验证其有效性。接受一个必选参数schema_path.

Fieldoptions

Thefollowingargumentsareavailabletoallfieldtypes.Allareoptional.

下面两个是对所有字段都有效的选项,两者都是可选值。

null

IfTrue,Djangowillstoreemptyvaluesas
NULLinthedatabase.Defaultis
False.

如果为True,Django会保存空字符串为NULL到数据库,默认是False.

Notethatemptystringvalueswillalwaysgetstoredasemptystrings,notas
NULL--sousenull=Truefornon-stringfieldssuchasintegers,booleansanddates.

注意空字符串会保存为空字符串,而不是NULL,所以对于非字符串类型的字段,比如整数,布尔值以及日期,需要设定null=True.

Avoidusingnullonstring-basedfieldssuchas
CharFieldand
TextFieldunlessyouhaveanexcellentreason.Ifastring-basedfieldhas
null=True,thatmeansithastwopossiblevaluesfor"nodata":
NULL,andtheemptystring.Inmostcases,it'sredundanttohavetwopossiblevaluesfor"nodata;"Djangoconventionistousetheemptystring,not
NULL.

对于基于字符串类型的字段如CharField,TextField要避免使用null.除非有特别的理由。如果一个基于字符串的字段类型设置了null=True,这就意味着有两种可能的值用于表示“没有数据”:NULL和空字符串。在大多数情况下,用两种值表示没有数据是冗余的,所以Django的惯例是使用空字符串,而不是NULL.

blank

IfTrue,thefieldisallowedtobeblank.

如果为True,该字段允许留空。

Notethatthisisdifferentthannull.
nullispurelydatabase-related,whereas
blankisvalidation-related.Ifafieldhas
blank=True,validationonDjango'sadminsitewillallowentryofanemptyvalue.Ifafieldhas
blank=False,thefieldwillberequired.

和null的区别:null是完全相对数据库的概念,而blank是对数据校验(validation)而言的。如果blank=True,则Django的admin后台校验功能会允许空值,否则字段为必填。

choices

Aniterable(e.g.,alistortuple)of2-tuplestouseaschoicesforthisfield.

由二元组的可枚举集合(list或tuple或其他)所代表的字段可选值。

Ifthisisgiven,Django'sadminwilluseaselectboxinsteadofthestandardtextfieldandwilllimitchoicestothechoicesgiven.

Django的admin会使用下拉框代替文本框,限制可选值的范围。

Achoiceslistlookslikethis:

YEAR_IN_SCHOOL_CHOICES=(
('FR','Freshman'),
('SO','Sophomore'),
('JR','Junior'),
('SR','Senior'),
('GR','Graduate'),
)

Thefirstelementineachtupleistheactualvaluetobestored.Thesecondelementisthehuman-readablenamefortheoption.

每个tuple的第一个元素是选项值,第二个是方便阅读的选项名称。

Thechoiceslistcanbedefinedeitheraspartofyourmodelclass:

可选值的列表可以定义在模型类里面:

classFoo(models.Model):
GENDER_CHOICES=(
('M','Male'),
('F','Female'),
)
gender=models.CharField(maxlength=1,choices=GENDER_CHOICES)

oroutsideyourmodelclassaltogether:

也可以定义在外部:

GENDER_CHOICES=(
('M','Male'),
('F','Female'),
)
classFoo(models.Model):
gender=models.CharField(maxlength=1,choices=GENDER_CHOICES)

Finally,notethatchoicescanbeanyiterableobject--notnecessarilyalistortuple.Thisletsyouconstructchoicesdynamically.Butifyoufindyourselfhacking
choicestobedynamic,you'reprobablybetteroffusingaproperdatabasetablewitha
ForeignKey.
choicesismeantforstaticdatathatdoesn'tchangemuch,ifever.

最后一点,请注意可选值可以是任意可枚举的对象:不一定要是list或tuple.这使得我们可以动态的构建选项集合对象。但是,如果你发现你需要动态构建选项列表对象时,也许使用一个外键表会更好,搭配ForeignKey字段设定。choices是为那些几乎从来不发生变化的静态选项集合而设定的。

core

Forobjectsthatareeditedinlinetoarelatedobject.

为了以内联的方式编辑对象,设定到一个关联对象的需要而设定。

IntheDjangoadmin,ifall"core"fieldsinaninline-editedobjectarecleared,theobjectwillbedeleted.

在Djangoadmin中,如果某个内联编辑(inline-edited)的对象的所有"core"字段都被清空,则该对象会被删除。

Itisanerrortohaveaninline-editablerelationwithoutatleastone
core=Truefield.

如果设定了内联编辑关系,却不设置至少一个core=True字段,这是做错误的。

Pleasenotethateachfieldmarked"core"istreatedasarequiredfieldbytheDjangoadminsite.Essentially,thismeansyoushouldput
core=Trueonallrequiredfieldsinyourrelatedobjectthatisbeingeditedinline.

注意,所有被标注为"core"的字段都会被DjangoAdmin当作必填字段。本质上,这就是说你需要对所有内联编辑的相关对象上加core=True字段。

db_column

Thenameofthedatabasecolumntouseforthisfield.Ifthisisn'tgiven,Djangowillusethefield'sname.

用于标注对应于字段属性的数据库列名称。如果不提供,则会直接使用字段属性的名称。

IfyourdatabasecolumnnameisanSQLreservedword,orcontainscharactersthataren'tallowedinPythonvariablenames--notably,thehyphen--that'sOK.Djangoquotescolumnandtablenamesbehindthescenes.

一般可以用这个办法来应付数据库字段和SQL保留字冲突的情况,或者和Python变量名冲突的情况(比如连字符不允许出现在Python变量名中)。

db_index

IfTrue,
django-admin.pysqlindexeswilloutputa
CREATEINDEXstatementforthisfield.

如果为True,django-admin.pysqlindexes会为此语句输出一个CREATEINDEX语句。

default

Thedefaultvalueforthefield.

字段的默认值

editable

IfFalse,thefieldwillnotbeeditableintheadmin.Defaultis
True.

如果为False,该字段在admin中不能被编辑。默认是True.

help_text

Extra"help"texttobedisplayedunderthefieldontheobject'sadminform.It'susefulfordocumentationevenifyourobjectdoesn'thaveanadminform.

用于显示在admin表单中的额外的帮助信息。即使不使用admin表单,这个字段也非常适合与文档功能。

primary_key

IfTrue,thisfieldistheprimarykeyforthemodel.

如果是True,该字段为主键。

Ifyoudon'tspecifyprimary_key=Trueforanyfieldsinyourmodel,Djangowillautomaticallyaddthisfield:

如果在某个模型中没有设置任何字段为primary_key=True,则Django会自动生成一个id字段:

id=models.AutoField('ID',primary_key=True)

Thus,youdon'tneedtosetprimary_key=Trueonanyofyourfieldsunlessyouwanttooverridethedefaultprimary-keybehavior.

一般不需要在任何字段上设置primary_key=True,除非你要覆盖自动产生id的行为。

primary_key=Trueimplies
blank=False,
null=Falseandunique=True.Onlyoneprimarykeyisallowedonanobject.

primary_key=True暗示着blank=False,null=False并且unique=True.一个对象只能有一个主键。

radio_admin

Bydefault,Django'sadminusesaselect-boxinterface(<select>)forfieldsthatare
ForeignKeyorhave
choicesset.Ifradio_adminissetto
True,Djangowillusearadio-buttoninterfaceinstead.

默认情况下,Djangoadmin用下拉框来选择ForeignKey或choices.如果设定radio_admin=True,则会用但旋钮代替。

Don'tusethisforafieldunlessit'saForeignKeyorhas
choicesset.

如果字段不是ForeignKey或choices,不要用这个属性。

unique

IfTrue,thisfieldmustbeuniquethroughoutthetable.

如果为True,则该字段值在表中是唯一的。

ThisisenforcedatthedatabaselevelandattheDjangoadmin-formlevel.

这个选项同时约束在数据库级别和Djangoadmin表单中。

unique_for_date

SetthistothenameofaDateFieldor
DateTimeFieldtorequirethatthisfieldbeuniqueforthevalueofthedatefield.

将这个属性值设定为某个DateField或DateTimeField字段的名称,使得此字段值相关的日期唯一。

Forexample,ifyouhaveafieldtitlethathas
unique_for_date="pub_date",thenDjangowouldn'tallowtheentryoftworecordswiththesame
titleand
pub_date.

举例来说,如果你有个字段title,在其上设定了unique_for_date="pub_date",那么Django就不会允许产生两条title和pub_date都相同的记录。

ThisisenforcedattheDjangoadmin-formlevelbutnotatthedatabaselevel.

这个限制仅在Djangoadmin-form上起作用,而不约束数据库。

unique_for_month

Likeunique_for_date,butrequiresthefieldtobeuniquewithrespecttothemonth.

和unique_for_date类似,但要求字段相对月份是唯一的。

unique_for_year

Likeunique_for_dateand
unique_for_month.

和unique_for_date以及unique_for_month类似。

validator_list

Alistofextravalidatorstoapplytothefield.Eachshouldbeacallablethattakestheparameters
field_data,
all_dataandraisesdjango.core.validators.ValidationErrorforerrors.(Seethe

validatordocs.)

针对该字段的一系列额外的验证器的列表。其中每个验证器都应该是callable,其参数为field_data,all_data,错误时抛出的异常为django.core.validators.ValidationError.

Djangocomeswithquiteafewvalidators.They'rein
django.core.validators.

Django自带了很多验证器,都在django.core.validators下。

Verbosefieldnames

Eachfieldtype,exceptforForeignKey,
ManyToManyFieldand
OneToOneField,takesanoptionalfirstpositionalargument--averbosename.Iftheverbosenameisn'tgiven,Djangowillautomaticallycreateitusingthefield'sattributename,convertingunderscorestospaces.

每个字段,除了ForeignKey,ManyToManyField和OneToOneField之外,可以接受第一个可选参数:即此字段的描述名称。如果没有提供,Django会根据属性名称自动创建一个,在此过程中,会把下划线转化为空格。

Inthisexample,theverbosenameis"Person's
firstname":

first_name=models.CharField("Person'sfirstname",maxlength=30)

Inthisexample,theverbosenameis"first
name":

first_name=models.CharField(maxlength=30)

ForeignKey,
ManyToManyFieldandOneToOneFieldrequirethefirstargumenttobeamodelclass,sousethe
verbose_namekeywordargument:

ForeignKey,ManyToManyField和OneToOneField要求第一个参数是一个Model类,因此需要用verbose_name这个关键字参数:

poll=models.ForeignKey(Poll,verbose_name="therelatedpoll")
sites=models.ManyToManyField(Site,verbose_name="listofsites")
place=models.OneToOneField(Place,verbose_name="relatedplace")

Conventionisnottocapitalizethefirstletterofthe
verbose_name.Djangowillautomaticallycapitalizethefirstletterwhereitneedsto.

惯例是verbose_name的首字母不需要大写。因为Django会在需要的时候把它自动转化为大写形式。

Relationships

关系

Clearly,thepowerofrelationaldatabasesliesinrelatingtablestoeachother.Djangoofferswaystodefinethethreemostcommontypesofdatabaserelationships:Many-to-one,many-to-manyandone-to-one.

很显然,关系型数据库的威力就在于表之间的相互关联。Django提供了办法来定义最常见的三种表间关联的类型:多对一,多对多,一对一。

Many-to-onerelationships

多对一关联

Todefineamany-to-onerelationship,useForeignKey.Youuseitjustlikeanyother
Fieldtype:byincludingitasaclassattributeofyourmodel.

要定义多对一关联,使用ForeignKey.只要像其他字段类型一样使用它即可:将它定义为Model类的一个属性。

ForeignKeyrequiresapositionalargument:Theclasstowhichthemodelisrelated.

ForeignKey需要一个位置确定的参数:和当前Model相关联的类。

Forexample,ifaCarmodelhasa
Manufacturer--thatis,a
Manufacturermakesmultiplecarsbuteach
Caronlyhasone
Manufacturer--usethefollowingdefinitions:

举例来说,如果一个汽车(Car)模型对应一个制造商(Manufacturer),也就是说,一个制造商生产多个汽车,但一个汽车只有一个制造商。可以使用如下方式定义这种关系:

classManufacturer(models.Model):
#...

classCar(models.Model):
manufacturer=models.ForeignKey(Manufacturer)
#...

Tocreatearecursiverelationship--anobjectthathasamany-to-onerelationshipwithitself--use
models.ForeignKey('self').

如果要创建递归的关系:即一个对象和它自身有多对一的关系,使用models.ForeignKey('self')

Ifyouneedtocreatearelationshiponamodelthathasnotyetbeendefined,youcanusethenameofthemodel,ratherthanthemodelobjectitself:

如果要创建一个关系,而它所依赖的模型还未被创建,你可以用模型的名称(字符串形式),而不是模型对象自身:

classCar(models.Model):
manufacturer=models.ForeignKey('Manufacturer')
#...

classManufacturer(models.Model):
#...

Note,however,thatsupportforstringsaroundmodelnamesin
ForeignKeyisquitenew,anditcanbebuggyinsomecases.

但是需要注意的是,这种用字符串形式的ForeignKey支持是比较新的特性,在某些情况下也许会产生bug.

Behindthescenes,Djangoappends"_id"tothefieldnametocreateitsdatabasecolumnname.Intheaboveexample,thedatabasetableforthe
Carmodelwillhavea
manufacturer_idcolumn.(Youcanchangethisexplicitlybyspecifying
db_column;see
db_columnbelow.)However,yourcodeshouldneverhavetodealwiththedatabasecolumnname,unlessyouwritecustomSQL.You'llalwaysdealwiththefieldnamesofyourmodelobject.

在幕后,Django向字段属性名称上附加"_id"来构成数据库的列名称。在上面的例子中,数据库中对应于Car模型的表会产生一个名为manufacturer_id的字段。(你也可以显式的指定它,通过db_column)。但是,你的代码应该从来不直接处理数据库列名称,除非你要写自定义的SQL.你应该总是操作模型对象的字段属性名。

It'ssuggested,butnotrequired,thatthenameofa
ForeignKeyfield(manufacturerintheexampleabove)bethenameofthemodel,lowercase.Youcan,ofcourse,callthefieldwhateveryouwant.Forexample:

有一个建议,但不是必须的:ForeignKey字段的名称(上述例子中的manufacturer)是对应模型类名称的小写。但你也可以将它取为任意的名称,比如:

classCar(models.Model):
company_that_makes_it=models.ForeignKey(Manufacturer)
#...

Seethe
Many-to-onerelationshipmodelexampleforafullexample.

ForeignKeyfieldstakeanumberofextraargumentsfordefininghowtherelationshipshouldwork.Allareoptional:

ForeignKey字段有一些额外的参数可以定义关系的具体形式,它们都是可选的:

ArgumentDescription
edit_inlineIfnotFalse,thisrelatedobjectisedited"inline"ontherelatedobject'spage.Thismeansthattheobjectwillnothaveitsownadmininterface.Useeither
models.TABULARor
models.STACKED,which,respectively,designatewhethertheinline-editableobjectsaredisplayedasatableorasa"stack"offieldsets.

如果不是False,则此对象会用内联的形式在相关对象页面直接编辑。这表示此对象没有它自己独立的管理界面。使用models.TABULAR或models.STACKED来标注,分别表示内联编辑的对象显示为表格还是fieldsets的stack.
limit_choices_toAdictionaryoflookupargumentsandvalues(seethe
DatabaseAPIreference)thatlimittheavailableadminchoicesforthisobject.Usethiswith
models.LazyDatetolimitchoicesofobjectsbydate.Forexample:

一个包含查找参数及其值的字典,用于限制对象可用的adminchoices,和models.LazyDate联用,用于按日期限制不同的选项,如:
limit_choices_to={'pub_date__lte':models.LazyDate()}

onlyallowsthechoiceofrelatedobjectswitha
pub_datebeforethecurrentdate/timetobechosen.

这个语句使得仅允许选择pub_date字段值在当前时间之前的那些日期。

InsteadofadictionarythiscanalsobeaQobject(anobjectwitha
get_sql()method)formorecomplexqueries.

和字典不同的是,在负责的查询中,这个也可以是一个Q对象(含有get_sql()方法的对象)

Notcompatiblewithedit_inline.

和edit_inline不相容。
max_num_in_adminForinline-editedobjects,thisisthemaximumnumberofrelatedobjectstodisplayintheadmin.Thus,ifapizzacouldonlyhaveupto10toppings,
max_num_in_admin=10wouldensurethatauserneverentersmorethan10toppings.

对于内联编辑的对象,这是显示在admin界面中相关对象的最大数目。
Notethatthisdoesn'tensuremorethan10relatedtoppingsevergetcreated.Itsimplycontrolstheadmininterface;itdoesn'tenforcethingsatthePythonAPIlevelordatabaselevel.

仅控制admin界面,对PythonAPI或数据库层次没有限制。
min_num_in_adminTheminimumnumberofrelatedobjectsdisplayedintheadmin.Normally,atthecreationstage,
num_in_admininlineobjectsareshown,andattheeditstage
num_extra_on_changeblankobjectsareshowninadditiontoallpre-existingrelatedobjects.However,nofewerthan
min_num_in_adminrelatedobjectswilleverbedisplayed.

在admin中显示的内联编辑对象的最少数目。通常,在创建阶段,会显示num_in_admin个内联对象,而在编辑阶段显示num_extra_on_change个额外的空对象。(排除已有的一些相关对象),然而,少于min_num_in_admin个相关对象的从来不被显示。
num_extra_on_changeThenumberofextrablankrelated-objectfieldstoshowatthechangestage.

对象在修改状态时,显示的额外的空白关联对象的数目。
num_in_adminThedefaultnumberofinlineobjectstodisplayontheobjectpageattheaddstage.

对象在添加状态时,显示的内联编辑的相关对象数目。
raw_id_adminOnlydisplayafieldfortheintegertobeenteredinsteadofadrop-downmenu.Thisisusefulwhenrelatedtoanobjecttypethatwillhavetoomanyrowstomakeaselectboxpractical.

仅显示一个可输入的整数值字段,而不是下拉列表。当关联对象在下拉框里显示会显得太多时,这很有用。
Notusedwithedit_inline.

不能和edit_inline选项一起设定。
related_nameThenametousefortherelationfromtherelatedobjectbacktothisone.Seethe

relatedobjectsdocumentationforafullexplanationandexample.

设定从关联对象到自身的关系名称。
to_fieldThefieldontherelatedobjectthattherelationisto.Bydefault,Djangousestheprimarykeyoftherelatedobject.

关联到的对象的字段名称。默认情况下,Django使用关联对象的主键字段。

Many-to-manyrelationships

多对多关联

Todefineamany-to-manyrelationship,useManyToManyField.Youuseitjustlikeanyother
Fieldtype:byincludingitasaclassattributeofyourmodel.

要定义多对多关联,用ManyToManyField.

ManyToManyFieldrequiresapositionalargument:Theclasstowhichthemodelisrelated.

ManyToManyField需要一个位置确定的参数:关联的模型的类名称。

Forexample,ifaPizzahasmultiple
Toppingobjects--thatis,a
Toppingcanbeonmultiplepizzasandeach
Pizzahasmultipletoppings--here'showyou'drepresentthat:

举例来说,假如一个Pizza可以有多个Topping对象:也就是说,每个Topping可以在多个pizza上面,并且每个Pizza可以有多个toppings.那么你可以用如下的办法来定义模型:

classTopping(models.Model):
#...

classPizza(models.Model):
#...
toppings=models.ManyToManyField(Topping)

AswithForeignKey,arelationshiptoselfcanbedefinedbyusingthestring
'self'insteadofthemodelname,andyoucanrefertoas-yetundefinedmodelsbyusingastringcontainingthemodelname.

和ForeignKey的设置一样,指向自身的多对多关联,可以用'self'来代替模型名称;指向尚未定义的模型时,可以用字符串形式表示。

It'ssuggested,butnotrequired,thatthenameofa
ManyToManyField(toppingsintheexampleabove)beapluraldescribingthesetofrelatedmodelobjects.

建议将ManyToManyField设置为复数形式,但这不是必须的。

Behindthescenes,Djangocreatesanintermediaryjointabletorepresentthemany-to-manyrelationship.

在幕后,Django会创建一个中间表来管理多对多关联。

Itdoesn'tmatterwhichmodelgetstheManyToManyField,butyouonlyneeditinoneofthemodels--notinboth.

在多对多关联的哪一方模型中定义ManyToManyField并不重要,但你只需要定义一次,而不是两边都定义。

Generally,ManyToManyFieldinstancesshouldgointheobjectthat'sgoingtobeeditedintheadmininterface,ifyou'reusingDjango'sadmin.Intheaboveexample,
toppingsisin
Pizza(ratherthanToppinghavinga
pizzas
ManyToManyField)becauseit'smorenaturaltothinkabouta
Pizzahavingtoppingsthanatoppingbeingonmultiplepizzas.Thewayit'ssetupabove,the
Pizzaadminformwouldletusersselectthetoppings.

一般的,ManyToManyField实例在admin界面中,会显示在其所属的对象的编辑界面,如果你使用Django的admin界面的话。在上述例子中,toppings显示在Pizza中,因为,我们说“一个Pizza有多个toppings"要比"一个topping在多个pizzas上面"来的更自然。按照上面的设置,在Pizza的管理界面上将会让你选择toppings来编辑。

Seethe
Many-to-manyrelationshipmodelexampleforafullexample.

ManyToManyFieldobjectstakeanumberofextraargumentsfordefininghowtherelationshipshouldwork.Allareoptional:

ManyToManyField的一些可选参数:

ArgumentDescription
related_nameSeethedescriptionunderForeignKeyabove.

同ForeignKey的情形
filter_interfaceUseaniftyunobtrusiveJavascript"filter"interfaceinsteadoftheusability-challenged
<selectmultiple>intheadminformforthisobject.Thevalueshouldbe
models.HORIZONTALor
models.VERTICAL(i.e.shouldtheinterfacebestackedhorizontallyorvertically).

在管理界面中,使用好看实用的JavaScript"filter"界面代替可用性受到挑战的<selectmultiple>.其值可以是models.HORIZONTAL或models.VERTICAL(指界面排序的方向)。
limit_choices_toSeethedescriptionunderForeignKeyabove.

同ForeignKey的情形
symmetrical

对称的
OnlyusedinthedefinitionofManyToManyFieldsonself.Considerthefollowingmodel:

仅在对自身有多对多关联时定义此选项。考虑下列模型:
classPerson(models.Model):friends=models.ManyToManyField("self")
WhenDjangoprocessesthismodel,itidentifiesthatithasa
ManyToManyFieldonitself,andasaresult,itdoesn'tadda
person_setattributetothe
Personclass.Instead,the
ManyToManyFieldisassumedtobesymmetrical--thatis,ifIamyourfriend,thenyouaremyfriend.

当Django处理这个模型时,它发现Person类有一个指向自身的ManyToManyField多对多关联,因此,它不会添加person_set属性到Person类中。相反的是,ManyToManyField被假定是对称的:也就是说,如果我是你的朋友,则你一定是我的朋友。

IfyoudonotwantsymmetryinManyToManyrelationshipswith
self,set
symmetricaltoFalse.ThiswillforceDjangotoaddthedescriptorforthereverserelationship,allowing
ManyToManyrelationshipstobenon-symmetrical.

如果你不想把指向自身的多对多关联定义为对称的,设置symmetrical=False即可。这会让Django为反向关系添加descriptor,已实现不对称的多对多关系。

One-to-onerelationships

一对一关联

Thesemanticsofone-to-onerelationshipswillbechangingsoon,sowedon'trecommendyouusethem.Ifthatdoesn'tscareyouaway,keepreading.

在未来的Django版本中,一对一关联的语义即将发生变化,因此我们不建议使用一对一关联。如果这没把你吓坏,继续阅读吧。

Todefineaone-to-onerelationship,useOneToOneField.Youuseitjustlikeanyother
Fieldtype:byincludingitasaclassattributeofyourmodel.

定义一对一关联使用OneToOneField字段即可。

Thisismostusefulontheprimarykeyofanobjectwhenthatobject"extends"anotherobjectinsomeway.

这对于通过和主键建立关联,扩展对象的属性为另一个对象的情形比较有用。

OneToOneFieldrequiresapositionalargument:Theclasstowhichthemodelisrelated.

一对一字段需要一个位置确定的参数:关联模型的类名称。

Forexample,ifyou'rebuildingadatabaseof"places",youwouldbuildprettystandardstuffsuchasaddress,phonenumber,etc.inthedatabase.Then,ifyouwantedtobuildadatabaseofrestaurantsontopoftheplaces,insteadofrepeatingyourself
andreplicatingthosefieldsintheRestaurantmodel,youcouldmake
Restauranthavea
OneToOneFieldtoPlace(becausearestaurant"is-a"place).

举例来说,如果你在建立一个关于“地点”信息的数据库,那么,你一定会建立一些很标准的信息,比如地址,电话号码等。那么如果你要建立另一个餐馆信息的数据库,而这些餐馆是基于上述“地点”信息的,你不需要通过复制地点信息的相关字段到“餐馆”模型中,而只要让“餐馆“建立到“地点”的一对一关联即可(OneToOneField).(因此“餐馆”是“地点”的一种)。

AswithForeignKey,arelationshiptoselfcanbedefinedbyusingthestring
"self"insteadofthemodelname;referencestoas-yetundefinedmodelscanbemadebyusingastringcontainingthemodelname.

和ForeignKey的情形一样,指向自身的一对一关联也可以用"self"来设定指向的模型名称;指向尚未定义的模型时,用字符串形式表示。

ThisOneToOneFieldwillactuallyreplacetheprimarykey
idfield(sinceone-to-onerelationssharethesameprimarykey),andwillbedisplayedasaread-onlyfieldwhenyoueditanobjectintheadmininterface:

OneToOneField会覆盖主键id字段(因此一对一关联共享一个主键),并且会在admin界面中会显示为一个只读字段。

Seethe
One-to-onerelationshipmodelexampleforafullexample.

Metaoptions

在模型类中添加内嵌的classMeta可以定义一些元数据信息:

classFoo(models.Model):
bar=models.CharField(maxlength=30)

classMeta:
#...

模型的元数据是除了字段声明之外的其他一些信息,比如排序选项等。

下面是所有Meta选项的列表,所有都不是必须的。

db_table

对应于模型的数据库表的名字:

db_table='music_album'

如果不给出这个选项,Django用下列格式自动生成一个表名:app_label
+'_'+
model_class_name.详细的参见下面的"Tablenames"部分。

如果你的表名是SQL保留字,或者包含Python中不允许出现在变量名中的字符(比如连字符),这不要紧。Django会在背后自动处理表名和列名的转换。

get_latest_by

是模型中某个DateField或
DateTimeField字段的名称。用于指定在模型的管理器中latest()方法会使用的默认字段。

例子:

get_latest_by="order_date"

Seethe
docsforlatest()formore.

order_with_respect_to

标注当前对象对给定的字段是可排序的。几乎总是被使用在允许按照某个父对象排序的关联对象中,比如,一个Answer对应于一个Question对象,而一个Question可以有多个Answer,而我们关心答案的次序。你可以这样写:

classAnswer(models.Model):
question=models.ForeignKey(Question)
#...

classMeta:
order_with_respect_to='question'


ordering

对象的默认排序规则。在获取对象列表时使用:

ordering=['-order_date']

这是一个字符串的list或tuple.每个字符串是一个字段名,它们可以有一个可选的前缀'-'字符,表示倒序排列。如果要随机次序排序,可以用"?"前缀。

例如,按pub_date字段升序排列:

ordering=['pub_date']

倒序:

ordering=['-pub_date']

先按pub_date降序,然后按author升序:

ordering=['-pub_date','author']

See
Specifyingorderingformoreexamples.

注意:不管在ordering中写了多少个字段,admin后台只用第一个。

permissions

创建对象时需要写到权限表中的额外的权限。对每一个有admin设置的对象,添加、修改、删除权限会自动创建。下面的例子定义了一个额外的权限:can_deliver_pizzas:

permissions=(("can_deliver_pizzas","Candeliverpizzas"),)

Thisisalistortupleof2-tuplesintheformat
(permission_code,human_readable_permission_name).

unique_together

(译注:类似于联合主键)定义哪些字段组合后是必须唯一的:

unique_together=(("driver","restaurant"),)

这个被用在Djangoadmin中,同时数据库中也会创建相关的约束。

Thisisalistoflistsoffieldsthatmustbeuniquewhenconsideredtogether.It'susedintheDjangoadminandisenforcedatthedatabaselevel(i.e.,theappropriate
UNIQUEstatementsareincludedinthe
CREATETABLEstatement).

verbose_name

Ahuman-readablenamefortheobject,singular:

verbose_name="pizza"

Ifthisisn'tgiven,Djangowilluseamungedversionoftheclassname:
CamelCasebecomescamel
case.

verbose_name_plural

Thepluralnamefortheobject:

verbose_name_plural="stories"

Ifthisisn'tgiven,Djangowilluseverbose_name
+"s".

Tablenames

Tosaveyoutime,Djangoautomaticallyderivesthenameofthedatabasetablefromthenameofyourmodelclassandtheappthatcontainsit.Amodel'sdatabasetablenameisconstructedbyjoiningthemodel's"applabel"--thenameyouusedin
manage.py
startapp--tothemodel'sclassname,withanunderscorebetweenthem.

Forexample,ifyouhaveanappbookstore(ascreatedby
manage.py
startappbookstore),amodeldefinedas
classBookwillhaveadatabasetablenamed
bookstore_book.

Tooverridethedatabasetablename,usethedb_tableparameterin
classMeta.

Automaticprimarykeyfields

Bydefault,Djangogiveseachmodelthefollowingfield:

id=models.AutoField(primary_key=True)

Thisisanauto-incrementingprimarykey.

Ifyou'dliketospecifyacustomprimarykey,justspecify
primary_key=Trueononeofyourfields.IfDjangoseesyou'veexplicitlyset
primary_key,itwon'taddtheautomatic
idcolumn.

Eachmodelrequiresexactlyonefieldtohaveprimary_key=True.

Adminoptions

IfyouwantyourmodeltobevisibletoDjango'sadminsite,giveyourmodelaninner
"classAdmin",likeso:

classPerson(models.Model):
first_name=models.CharField(maxlength=30)
last_name=models.CharField(maxlength=30)

classAdmin:
#Adminoptionsgohere
pass

TheAdminclasstellsDjangohowtodisplaythemodelintheadminsite.

Here'salistofallpossibleAdminoptions.Noneoftheseoptionsarerequired.Touseanadmininterfacewithoutspecifyinganyoptions,use
pass,likeso:

classAdmin:
pass

Addingclass
Admintoamodeliscompletelyoptional.

date_hierarchy

Setdate_hierarchytothenameofa
DateFieldor
DateTimeFieldinyourmodel,andthechangelistpagewillincludeadate-baseddrilldownnavigationbythatfield.

Example:

date_hierarchy='pub_date'


fields

Setfieldstocontrolthelayoutofadmin"add"and"change"pages.

fieldsisalistoftwo-tuples,inwhicheachtwo-tuplerepresentsa
<fieldset>ontheadminformpage.(A
<fieldset>isa"section"oftheform.)

Thetwo-tuplesareintheformat(name,
field_options),where
nameisastringrepresentingthetitleofthefieldsetand
field_optionsisadictionaryofinformationaboutthefieldset,includingalistoffieldstobedisplayedinit.

Afullexample,takenfromthedjango.contrib.flatpages.FlatPagemodel:

classAdmin:
fields=(
(None,{
'fields':('url','title','content','sites')
}),
('Advancedoptions',{
'classes':'collapse',
'fields':('enable_comments','registration_required','template_name')
}),
)

Thisresultsinanadminpagethatlookslike:



Iffieldsisn'tgiven,Djangowilldefaulttodisplayingeachfieldthatisn'tan
AutoFieldandhas
editable=True,inasinglefieldset,inthesameorderasthefieldsaredefinedinthemodel.

Thefield_optionsdictionarycanhavethefollowingkeys:

fields

Atupleoffieldnamestodisplayinthisfieldset.Thiskeyisrequired.

Example:

{
'fields':('first_name','last_name','address','city','state'),
}

Todisplaymultiplefieldsonthesameline,wrapthosefieldsintheirowntuple.Inthisexample,the
first_nameand
last_namefieldswilldisplayonthesameline:

{
'fields':(('first_name','last_name'),'address','city','state'),
}


classes

AstringcontainingextraCSSclassestoapplytothefieldset.

Example:

{
'classes':'wide',
}

Applymultipleclassesbyseparatingthemwithspaces.Example:

{
'classes':'wideextrapretty',
}

Twousefulclassesdefinedbythedefaultadmin-sitestylesheetare
collapseandwide.Fieldsetswiththe
collapsestylewillbeinitiallycollapsedintheadminandreplacedwithasmall"clicktoexpand"link.Fieldsetswiththe
widestylewillbegivenextrahorizontalspace.

description

Astringofoptionalextratexttobedisplayedatthetopofeachfieldset,undertheheadingofthefieldset.It'susedverbatim,soyoucanuseanyHTMLandyoumustescapeanyspecialHTMLcharacters(suchasampersands)yourself.

js

AlistofstringsrepresentingURLsofJavaScriptfilestolinkintotheadminscreenvia
<scriptsrc="">tags.ThiscanbeusedtotweakagiventypeofadminpageinJavaScriptortoprovide"quicklinks"tofillindefaultvaluesforcertainfields.

list_display

Setlist_displaytocontrolwhichfieldsaredisplayedonthechangelistpageoftheadmin.

Example:

list_display=('first_name','last_name')

Ifyoudon'tsetlist_display,theadminsitewilldisplayasinglecolumnthatdisplaysthe
__str__()representationofeachobject.

Afewspecialcasestonoteaboutlist_display:

IfthefieldisaForeignKey,Djangowilldisplaythe
__str__()oftherelatedobject.

ManyToManyFieldfieldsaren'tsupported,becausethatwouldentail

executingaseparateSQLstatementforeachrowinthetable.

IfthefieldisaBooleanField,Djangowilldisplayapretty"on"or"off"iconinsteadof
Trueor
False.

Ifthestringgivenisamethodofthemodel,Djangowillcallitanddisplaytheoutput.Thismethodshouldhavea
short_descriptionfunctionattribute,foruseastheheaderforthefield.
Here'safullexamplemodel:

classPerson(models.Model):
name=models.CharField(maxlength=50)
birthday=models.DateField()

classAdmin:
list_display=('name','decade_born_in')

defdecade_born_in(self):
returnself.birthday.strftime('%Y')[:3]+"0's"
decade_born_in.short_description='Birthdecade'


Ifthestringgivenisamethodofthemodel,DjangowillHTML-escapetheoutputbydefault.Ifyou'drathernotescapetheoutputofthemethod,givethemethodan
allow_tagsattributewhosevalueis
True.
Here'safullexamplemodel:

classPerson(models.Model):
first_name=models.CharField(maxlength=50)
last_name=models.CharField(maxlength=50)
color_code=models.CharField(maxlength=6)

classAdmin:
list_display=('first_name','last_name','colored_name')

defcolored_name(self):
return'<spanstyle="color:#%s;">%s%s</span>'%(self.color_code,self.first_name,self.last_name)
colored_name.allow_tags=True


list_display_links

Setlist_display_linkstocontrolwhichfieldsin
list_displayshouldbelinkedtothe"change"pageforanobject.

Bydefault,thechangelistpagewilllinkthefirstcolumn--thefirstfieldspecifiedin
list_display--tothechangepageforeachitem.But
list_display_linksletsyouchangewhichcolumnsarelinked.Set
list_display_linkstoalistortupleoffieldnames(inthesameformatas
list_display)tolink.

list_display_linkscanspecifyoneormanyfieldnames.Aslongasthefieldnamesappearin
list_display,Djangodoesn'tcarehowmany(orhowfew)fieldsarelinked.Theonlyrequirementis:Ifyouwanttouse
list_display_links,youmustdefine
list_display.

Inthisexample,thefirst_nameand
last_namefieldswillbelinkedonthechangelistpage:

classAdmin:
list_display=('first_name','last_name','birthday')
list_display_links=('first_name','last_name')

Finally,notethatinordertouselist_display_links,youmustdefine
list_display,too.

list_filter

Setlist_filtertoactivatefiltersintherightsidebarofthechangelistpageoftheadmin.Thisshouldbealistoffieldnames,andeachspecifiedfieldshouldbeeithera
BooleanField,
DateField,DateTimeFieldor
ForeignKey.

Thisexample,takenfromthedjango.contrib.auth.models.Usermodel,showshowboth
list_displayand
list_filterwork:

classAdmin:
list_display=('username','email','first_name','last_name','is_staff')
list_filter=('is_staff','is_superuser')

Theabovecoderesultsinanadminchangelistpagethatlookslikethis:



(Thisexamplealsohassearch_fieldsdefined.Seebelow.)

list_per_page

Setlist_per_pagetocontrolhowmanyitemsappearoneachpaginatedadminchangelistpage.Bydefault,thisissetto
100.

list_select_related

Setlist_select_relatedtotellDjangotouse
select_related()inretrievingthelistofobjectsontheadminchangelistpage.Thiscansaveyouabunchofdatabasequeries.

ThevalueshouldbeeitherTrueor
False.Defaultis
False.

NotethatDjangowilluseselect_related(),regardlessofthissetting,ifoneofthe
list_displayfieldsisa
ForeignKey.

Formoreonselect_related(),see

theselect_related()docs.

ordering

Setorderingtospecifyhowobjectsontheadminchangelistpageshouldbeordered.Thisshouldbealistortupleinthesameformatasamodel's
orderingparameter.

Ifthisisn'tprovided,theDjangoadminwillusethemodel'sdefaultordering.

save_as

Setsave_astoenablea"saveas"featureonadminchangeforms.

Normally,objectshavethreesaveoptions:"Save","Saveandcontinueediting"and"Saveandaddanother".If
save_asis
True,"Saveandaddanother"willbereplacedbya"Saveas"button.

"Saveas"meanstheobjectwillbesavedasanewobject(withanewID),ratherthantheoldobject.

Bydefault,save_asissetto
False.

save_on_top

Setsave_on_toptoaddsavebuttonsacrossthetopofyouradminchangeforms.

Normally,thesavebuttonsappearonlyatthebottomoftheforms.Ifyouset
save_on_top,thebuttonswillappearbothonthetopandthebottom.

Bydefault,save_on_topissetto
False.

search_fields

Setsearch_fieldstoenableasearchboxontheadminchangelistpage.Thisshouldbesettoalistoffieldnamesthatwillbesearchedwheneversomebodysubmitsasearchqueryinthattextbox.

Thesefieldsshouldbesomekindoftextfield,suchas
CharFieldorTextField.

Whensomebodydoesasearchintheadminsearchbox,Djangosplitsthesearchqueryintowordsandreturnsallobjectsthatcontaineachofthewords,caseinsensitive,whereeachwordmustbeinatleastoneof
search_fields.Forexample,if
search_fieldsissetto
['first_name',
'last_name']andausersearchesforjohn
lennon,DjangowilldotheequivalentofthisSQL
WHEREclause:

WHERE(first_nameILIKE'%john%'ORlast_nameILIKE'%john%')
AND(first_nameILIKE'%lennon%'ORlast_nameILIKE'%lennon%')


Managers

AManageristheinterfacethroughwhichdatabasequeryoperationsareprovidedtoDjangomodels.Atleastone
ManagerexistsforeverymodelinaDjangoapplication.

ThewayManagerclassesworkisdocumentedinthe

RetrievingobjectssectionofthedatabaseAPIdocs,butthissectionspecificallytouchesonmodeloptionsthatcustomize
Managerbehavior.

Managernames

Bydefault,DjangoaddsaManagerwiththename
objectstoeveryDjangomodelclass.However,ifyouwanttouse
objectsasafieldname,orifyouwanttouseanameotherthan
objectsforthe
Manager,youcanrenameitonaper-modelbasis.Torenamethe
Managerforagivenclass,defineaclassattributeoftype
models.Manager()onthatmodel.Forexample:

fromdjango.dbimportmodels

classPerson(models.Model):
#...
people=models.Manager()

Usingthisexamplemodel,Person.objectswillgeneratean
AttributeErrorexception,but
Person.people.all()willprovidealistofall
Personobjects.

CustomManagers

YoucanuseacustomManagerinaparticularmodelbyextendingthebase
Managerclassandinstantiatingyourcustom
Managerinyourmodel.

Therearetworeasonsyoumightwanttocustomizea
Manager:toaddextra
Managermethods,and/ortomodifytheinitial
QuerySettheManagerreturns.

AddingextraManagermethods

AddingextraManagermethodsisthepreferredwaytoadd"table-level"functionalitytoyourmodels.(For"row-level"functionality--i.e.,functionsthatactonasingleinstanceofamodelobject
--useModelmethods,notcustom
Managermethods.)

AcustomManagermethodcanreturnanythingyouwant.Itdoesn'thavetoreturna
QuerySet.

Forexample,thiscustomManageroffersamethod
with_counts(),whichreturnsalistofall
OpinionPollobjects,eachwithanextra
num_responsesattributethatistheresultofanaggregatequery:

classPollManager(models.Manager):
defwith_counts(self):
fromdjango.dbimportconnection
cursor=connection.cursor()
cursor.execute("""
SELECTp.id,p.question,p.poll_date,COUNT(*)
FROMpolls_opinionpollp,polls_responser
WHEREp.id=r.poll_id
GROUPBY1,2,3
ORDERBY3DESC""")
result_list=[]
forrowincursor.fetchall():
p=self.model(id=row[0],question=row[1],poll_date=row[2])
p.num_responses=row[3]
result_list.append(p)
returnresult_list

classOpinionPoll(models.Model):
question=models.CharField(maxlength=200)
poll_date=models.DateField()
objects=PollManager()

classResponse(models.Model):
poll=models.ForeignKey(Poll)
person_name=models.CharField(maxlength=50)
response=models.TextField()

Withthisexample,you'duseOpinionPoll.objects.with_counts()toreturnthatlistof
OpinionPollobjectswith
num_responsesattributes.

Anotherthingtonoteaboutthisexampleisthat
Managermethodscanaccess
self.modeltogetthemodelclasstowhichthey'reattached.

ModifyinginitialManagerQuerySets

AManager'sbase
QuerySetreturnsallobjectsinthesystem.Forexample,usingthismodel:

classBook(models.Model):
title=models.CharField(maxlength=100)
author=models.CharField(maxlength=50)

...thestatementBook.objects.all()willreturnallbooksinthedatabase.

YoucanoverrideaManager'sbase
QuerySetbyoverridingthe
Manager.get_query_set()method.
get_query_set()shouldreturna
QuerySetwiththepropertiesyourequire.

Forexample,thefollowingmodelhastwo
Managers--onethatreturnsallobjects,andonethatreturnsonlythebooksbyRoaldDahl:

#First,definetheManagersubclass.
classDahlBookManager(models.Manager):
defget_query_set(self):
returnsuper(DahlBookManager,self).get_query_set().filter(author='RoaldDahl')

#ThenhookitintotheBookmodelexplicitly.
classBook(models.Model):
title=models.CharField(maxlength=100)
author=models.CharField(maxlength=50)

objects=models.Manager()#Thedefaultmanager.
dahl_objects=DahlBookManager()#TheDahl-specificmanager.

Withthissamplemodel,Book.objects.all()willreturnallbooksinthedatabase,but
Book.dahl_objects.all()willonlyreturntheoneswrittenbyRoaldDahl.

Ofcourse,becauseget_query_set()returnsa
QuerySetobject,youcanuse
filter(),
exclude()andalltheother
QuerySetmethodsonit.Sothesestatementsarealllegal:

Book.dahl_objects.all()
Book.dahl_objects.filter(title='Matilda')
Book.dahl_objects.count()

Thisexamplealsopointedoutanotherinterestingtechnique:usingmultiplemanagersonthesamemodel.Youcanattachasmany
Manager()instancestoamodelasyou'dlike.Thisisaneasywaytodefinecommon"filters"foryourmodels.

Forexample:

classMaleManager(models.Manager):
defget_query_set(self):
returnsuper(MaleManager,self).get_query_set().filter(sex='M')

classFemaleManager(models.Manager):
defget_query_set(self):
returnsuper(FemaleManager,self).get_query_set().filter(sex='F')

classPerson(models.Model):
first_name=models.CharField(maxlength=50)
last_name=models.CharField(maxlength=50)
sex=models.CharField(maxlength=1,choices=(('M','Male'),('F','Female')))
people=models.Manager()
men=MaleManager()
women=FemaleManager()

ThisexampleallowsyoutorequestPerson.men.all(),
Person.women.all(),and
Person.people.all(),yieldingpredictableresults.

IfyouusecustomManagerobjects,takenotethatthefirst
ManagerDjangoencounters(inorderbywhichthey'redefinedinthemodel)hasaspecialstatus.Djangointerpretsthefirst
Managerdefinedinaclassasthe"default"
Manager.Certainoperations--suchasDjango'sadminsite--usethedefault
Managertoobtainlistsofobjects,soit'sgenerallyagoodideaforthefirst
Managertoberelativelyunfiltered.Inthelastexample,the
people
Managerisdefinedfirst--soit'sthedefault
Manager.

Modelmethods

Definecustommethodsonamodeltoaddcustom"row-level"functionalitytoyourobjects.Whereas
Managermethodsareintendedtodo"table-wide"things,modelmethodsshouldactonaparticularmodelinstance.

Thisisavaluabletechniqueforkeepingbusinesslogicinoneplace--themodel.

Forexample,thismodelhasafewcustommethods:

classPerson(models.Model):
first_name=models.CharField(maxlength=50)
last_name=models.CharField(maxlength=50)
birth_date=models.DateField()
address=models.CharField(maxlength=100)
city=models.CharField(maxlength=50)
state=models.USStateField()#Yes,thisisAmerica-centric...

defbaby_boomer_status(self):
"Returnstheperson'sbaby-boomerstatus."
importdatetime
ifdatetime.date(1945,8,1)<=self.birth_date<=datetime.date(1964,12,31):
return"Babyboomer"
ifself.birth_date<datetime.date(1945,8,1):
return"Pre-boomer"
return"Post-boomer"

defis_midwestern(self):
"ReturnsTrueifthispersonisfromtheMidwest."
returnself.statein('IL','WI','MI','IN','OH','IA','MO')

def_get_full_name(self):
"Returnstheperson'sfullname."
return'%s%s'%(self.first_name,self.last_name)
full_name=property(_get_full_name)

Thelastmethodinthisexampleisaproperty.
Readmoreaboutproperties.

Afewobjectmethodshavespecialmeaning:

__str__

__str__()isaPython"magicmethod"thatdefineswhatshouldbereturnedifyoucall
str()ontheobject.Djangouses
str(obj)inanumberofplaces,mostnotablyasthevaluedisplayedtorenderanobjectintheDjangoadminsiteandasthevalueinsertedintoatemplatewhenitdisplaysanobject.Thus,youshould
alwaysreturnanice,human-readablestringfortheobject's
__str__.Althoughthisisn'trequired,it'sstronglyencouraged.

Forexample:

classPerson(models.Model):
first_name=models.CharField(maxlength=50)
last_name=models.CharField(maxlength=50)

def__str__(self):
return'%s%s'%(self.first_name,self.last_name)


get_absolute_url

Defineaget_absolute_url()methodtotellDjangohowtocalculatetheURLforanobject.Forexample:

defget_absolute_url(self):
return"/people/%i/"%self.id

Djangousesthisinitsadmininterface.Ifanobjectdefines
get_absolute_url(),theobject-editingpagewillhavea"Viewonsite"linkthatwilljumpyoudirectlytotheobject'spublicview,accordingto
get_absolute_url().

Also,acoupleofotherbitsofDjango,suchasthesyndication-feedframework,use
get_absolute_url()asaconveniencetorewardpeoplewho'vedefinedthemethod.

It'sgoodpracticetouseget_absolute_url()intemplates,insteadofhard-codingyourobjects'URLs.Forexample,thistemplatecodeisbad:

<ahref="/people/{{object.id}}/">{{object.name}}</a>

Butthistemplatecodeisgood:

<ahref="{{object.get_absolute_url}}">{{object.name}}</a>

(Yes,weknowget_absolute_url()couplesURLstomodels,whichviolatestheDRYprinciple,becauseURLsaredefinedbothinaURLconfandinthemodel.Thisisararecaseinwhichwe'veintentionally
violatedthatprincipleforthesakeofconvenience.Withthatsaid,we'reworkingonanevencleanerwayofspecifyingURLsinamoreDRYfashion.)

ExecutingcustomSQL

FeelfreetowritecustomSQLstatementsincustommodelmethodsandmodule-levelmethods.Theobject
django.db.connectionrepresentsthecurrentdatabaseconnection.Touseit,call
connection.cursor()togetacursorobject.Then,call
cursor.execute(sql,
[params])toexecutetheSQLandcursor.fetchone()or
cursor.fetchall()toreturntheresultingrows.Example:

defmy_custom_sql(self):
fromdjango.dbimportconnection
cursor=connection.cursor()
cursor.execute("SELECTfooFROMbarWHEREbaz=%s",[self.baz])
row=cursor.fetchone()
returnrow

connectionand
cursorsimplyusethestandard
PythonDB-API.Ifyou'renotfamiliarwiththePythonDB-API,notethattheSQLstatementin
cursor.execute()usesplaceholders,
"%s",ratherthanaddingparametersdirectlywithintheSQL.Ifyouusethistechnique,theunderlyingdatabaselibrarywillautomaticallyaddquotesandescapingtoyourparameter(s)asnecessary.
(AlsonotethatDjangoexpectsthe"%s"placeholder,
notthe"?"placeholder,whichisusedbytheSQLitePythonbindings.Thisisforthesakeofconsistencyandsanity.)

Afinalnote:IfallyouwanttodoisacustomWHEREclause,youcanjustjustthe
where,
tablesandparamsargumentstothestandardlookupAPI.See

Otherlookupoptions.

Overridingdefaultmodelmethods

Asexplainedinthe
databaseAPIdocs,eachmodelgetsafewmethodsautomatically--mostnotably,
save()and
delete().Youcanoverridethesemethodstoalterbehavior.

Aclassicuse-caseforoverridingthebuilt-inmethodsisifyouwantsomethingtohappenwheneveryousaveanobject.Forexample:

classBlog(models.Model):
name=models.CharField(maxlength=100)
tagline=models.TextField()

defsave(self):
do_something()
super(Blog,self).save()#Callthe"real"save()method.
do_something_else()

Youcanalsopreventsaving:

classBlog(models.Model):
name=models.CharField(maxlength=100)
tagline=models.TextField()

defsave(self):
ifself.name=="YokoOno'sblog":
return#Yokoshallneverhaveherownblog!
else:
super(Blog,self).save()#Callthe"real"save()method.


Modelsacrossfiles

It'sperfectlyOKtorelateamodeltoonefromanotherapp.Todothis,justimporttherelatedmodelatthetopofthemodelthatholdsyourmodel.Then,justrefertotheothermodelclasswhereverneeded.Forexample:

frommysite.geography.modelsimportZipCode

classRestaurant(models.Model):
#...
zip_code=models.ForeignKey(ZipCode)


Usingmodels

Onceyouhavecreatedyourmodels,thefinalstepistotellDjangoyou'regoingto
usethosemodels.

Dothisbyeditingyoursettingsfileandchangingthe
INSTALLED_APPSsettingtoaddthenameofthemodulethatcontainsyour
models.py.

Forexample,ifthemodelsforyourapplicationliveinthemodule
mysite.myapp.models(thepackagestructurethatiscreatedforanapplicationbythe
manage.py
startappscript),INSTALLED_APPSshouldread,inpart:

INSTALLED_APPS=(
#...
'mysite.myapp',
#...
)


ProvidinginitialSQLdata

DjangoprovidesahookforpassingthedatabasearbitrarySQLthat'sexecutedjustaftertheCREATETABLEstatements.Usethishook,forexample,ifyouwanttopopulatedefaultrecords,orcreateSQLfunctions,automatically.

Thehookissimple:Djangojustlooksforafilecalled
<appname>/sql/<modelname>.sql,where
<appname>isyourappdirectoryand
<modelname>isthemodel'snameinlowercase.

InthePersonexamplemodelatthetopofthisdocument,assumingitlivesinanappcalled
myapp,youcouldaddarbitrarySQLtothefile
myapp/sql/person.sql.Here'sanexampleofwhatthefilemightcontain:

INSERTINTOmyapp_person(first_name,last_name)VALUES('John','Lennon');
INSERTINTOmyapp_person(first_name,last_name)VALUES('Paul','McCartney');

EachSQLfile,ifgiven,isexpectedtocontainvalidSQL.TheSQLfilesarepipeddirectlyintothedatabaseafterallofthemodels'table-creationstatementshavebeenexecuted.

TheSQLfilesarereadbythesqlinitialdata,
sqlreset,
sqlallandresetcommandsin
manage.py.Refertothe

manage.pydocumentationformoreinformation.

NotethatifyouhavemultipleSQLdatafiles,there'snoguaranteeoftheorderinwhichthey'reexecuted.Theonlythingyoucanassumeisthat,bythetimeyourcustomdatafilesareexecuted,allthedatabasetablesalreadywillhavebeencreated.

Database-backend-specificSQLdata

There'salsoahookforbackend-specificSQLdata.Forexample,youcanhaveseparateinitial-datafilesforPostgreSQLandMySQL.Foreachapp,Djangolooksforafilecalled
<appname>/sql/<modelname>.<backend>.sql,where
<appname>isyourappdirectory,
<modelname>isthemodel'snameinlowercaseand
<backend>isthevalueof
DATABASE_ENGINEinyoursettingsfile(e.g.,
postgresql,
mysql).

Backend-specificSQLdataisexecutedbeforenon-backend-specificSQLdata.Forexample,ifyourappcontainsthefiles
sql/person.sqland
sql/person.postgresql.sqlandyou'reinstallingtheapponPostgreSQL,Djangowillexecutethecontentsof
sql/person.postgresql.sqlfirst,then
sql/person.sql.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: