安装数据库驱动程序pipinstallmysqlclient(对应Python包为MySQLdb)
编辑settings.py中DATABASES的参数、时区
DATABASES={default:{#ENGINE:django.db.backends.sqlite3,#NAME:os.path.join(BASE_DIR,db.sqlite3),ENGINE:django.db.backends.mysql,NAME:test,USER:root,HOST:localhost,PORT:,PASSWORD:*******,}}#TIME_ZONE=UTCTIME_ZONE=Asia/Shanghai
数据库移植
pythonmanage.pymakemigrationspythonmanage.pymigrate数据迁移
将DATABASES的参数改成初始参数,执行pythonmanage.pydumpdatadata.json再将DATABASES的参数改成MySQL参数,执行pythonmanage.pyloaddatadata.json从已有数据表生成模型DjangoORM的migrate命令适合从零启动一个项目,并让django自动跟踪modelclass的变动,可以实现完全脱离手动SQL操作构建项目。但更多时候,我们的项目都会从现有的数据库着手开发,此时可以使用inpectdb命令从已有数据表生成模型。
执行pythonmanage.pyinspectdb,检查终端中生成的模型代码,并确认无误(符合Django规范)执行pythonmanage.pyinspectdbmodels.py,此时会输出内容到当前目录的models.py中,复制从已有数据表生成的模型代码到对应app的models.py可选:删除生成模型代码classMeta中managed=False(或改为managed=True),将数据表交给Django管理维护。原因:在开发的场景中,如果是接入一个外部数据表,由第三方开发的程序管理(在这种情况下,Django并不需要负责维护这个数据库,只实现ReadOnly功能,数据库内容的增删改由另一套程序负责。)而Django不负责维护改数据库,或者说model中的改动不需要更新到数据库,那么保持managed=False执行pythonmanage.pymakemigrations、pythonmanage.pymigrate基本操作每个模型类都可以被映射为数据库中的一个数据表,类属性被映射为数据字段,数据库表的主键、外键、约束也通过类属性完成定义
模型类定义的基本结构
#所有模型类都继承自django.db.models.Modelfromdjango.dbimportmodelsclassModelName(models.Model):#通过类属性定义模型字段field1=models.XXField(...)field2=models.XXField(...)...#通过Meta子类属性定义模型元数据classMeta:db_table=...other_mates=...
Meta类属性由Django预定义,常用Meta类属性如下
abstract:bool,标识本类是否为抽象基类app_label:str,定义本类所属应用db_table:str,映射的数据表名default_related_name:str,定义模型的反向关系引用名称,默认模型名一致get_latest_by:str,定义按哪个字段值排列以获得模型的开始或结束记录,本属性值通常指向一个日期或整型的模型字段managed:bool,定义Django的manage.py命令行工具是否管理本模型,默认为True,若设为False,则运行pythonmanage.pymigrate时将不会在数据库生成本模型的数据表,需要手工维护数据库的定义order_with_respect_to:?,定义本模型可以按照某外键引用的关系排列ordering:list[str],本模型记录的默认排序字段,可设置多个字段,默认升序,若要以降序排列则需要在字段名前加“符号”default_permissions:tuple(str),模型操作权限,默认为(add,change,delete)proxy:bool,本模型和所有继承自本模型的子模型是否为代理模型required_db_features:list[str],定义底层数据库所必须具备的特性,[gis_enabled]只将本数据模型生成在满足gis_enabled特性的数据库中required_db_features:str,定义底层数据库类型,如果定义本属性,则模型只能在声明的数据库中被维护unique_together:用来设置不重复的字段组合#每个user_name在同一个pub_date中只能有一条数据表记录classMeta:unique_together=(("user_name","pub_date"),)index_together:定义联合索引字段,可设置多个
classMeta:index_together=[["pub_date","deadline"],]verbose_name:str,指明一个易于理解和表述的单数形式名词作为模型类的对象的名称verbose_name:str,指明一个易于理解和表述的复数形式名词作为模型类的对象的名称
类属性定义模型字段,普通字段类型指模型类中除外键关系外的数据字段的类型,以下是若干常用的类型:
Autofield:一个自动增加的整型字段,添加记录时会自动增长,通常用于充当数据表主键,若模型中未设置主键字段,Django自动添加一个AutoField字段BooleanField:布尔字段,对应inputtype="checkbox"CharField:较短字符串字段,对应inputtype="text"TextField:大容量文本字段,对应textareaDateField:日期字段DateTimeField:支持时间输入的日期字段常用字段参数
null:定义是否允许相应数据库字段为Null,默认为False,数据库非空约束blank:定义字段是否可以为空,用于字段HTML表单验证,判断用户是否可以不输入数据choices:定义字段可选值#choices的值是一个包含二维元素的元组#元组元素第一个值是实际存储值,第二个值是HTML显示值LEVELS=((1,A),(2,B),(3,C))default:设定默认值help_text:HTML页面输入控件的帮助字符串primary_key:bool,定义字段是否为主键unique:是否为字段定义数据库的唯一约束无名参数:设置该字段在HTML页面的人性化名称,models.CharField("请为本条信息评级",max_length=1,choices=LEVELS)
基本查询
fromdjango.dbimportmodelsclassComment(models.Model):id=models.AutoField(primary_key=True)headline=models.CharField(max_length=)body_text=models.TextField()pub_date=models.DateField()n_visits=models.IntegerField()def__str__(self):returnself.headline
查询模型所有数据:Comment.objects.all()
Comment.objects.all()[:10]#查询前10条记录Comment.objects.all()[10:20]#查询从第11~20条记录Comment.objects.all()[1]#查询第二条记录
查询单条数据:Comment.objects.get(id_exact=1)
过滤器:filter(**kwargs)返回符合筛选条件的数据集、exclude(**kwargs)返回不符合筛选条件的数据集
#多个过滤器可以链接在一起查询Comment.objects.filter(pub_date__year=).exclude(pub_date__month=1).exclude(n_visits__exact=0)
筛选条件的fieldlookup表达方式:字段名称__谓词
谓词含义筛选条件示例SQL等价where子句exact精确等于id__exact=14whereid=14iexact大小写不敏感headline__iexact=likewhereupper(headline)="LIKE"contains模糊匹配headline__contains="good"whereheadlinelike"%good%"in包含id_in=[1,5,9]whereidin(1,5,9)gtn_visits__gt=30n_visits30gte=ltlte=startwith以...开头body_text__startwith="Hello"wherebody_textlikeHello%endswith以...结尾range在...范围内pub_date__range=(datetime.date(,1,1),datetime.date(,2,1))wherepub_datebetween-1-1and-2-1year、month、day、week_day年、月、日、周几pub_date__year=isnull是否为空pub_date__isnull=Truewherepub_dateisNULL数据排序:Comment.objects.order_by(headline)
数据保存和删除
保存:obj.save()删除:#删除多条数据Comment.objects.filter(pub_date__year=).delete()#删除单条数据Comment.objects.get(id=3).delete()关系操作
通过OneToOneField字段定义一对一关系(1:1)
fromdjango.dbimportmodelsclassAccount(models.model):user_name=models.CharField(max_length=80)password=models.CharField(max_length=)reg_date=models.DateField()def__unicode__():return"Account:%s"%self.user_nameclassContact(models.Model):account=models.OneToOneField(Account,#被关联的模型名on_delete=models.CASCADE,#定义Account的记录被删除时本模型的记录如何处理,CASCADE用于定义本模型关联记录也被删除primary_key=True,)#通过OneToOneField类型的account字段定义一对一关系zip_code=models.CharField(max_length=10)address=models.CharField(max_length=80)mobile=models.CharField(max_length=20)def__unicode__(self):#定义模型显示字符串return"%s,%s"%(self.account.user_name,mobile)
通过ForeignKey字段定义一对多关系(1:N)
fromdjango.dbimportmodelsclassAccount(models.model):user_name=models.CharField(max_length=80)password=models.CharField(max_length=)reg_date=models.DateField()def__unicode__():return"Account:%s"%self.user_nameclassContact(models.Model):#定义ForeignKey字段的模型是附模型,Account是主模型#主模型对象通过xxxx_set访问附模型对象集合,如a1.contact_setaccount=models.ForeignKey(Account,on_delete=models.CASCADE)zip_code=models.CharField(max_length=10)address=models.CharField(max_length=80)mobile=models.CharField(max_length=20)def__unicode__(self):#定义模型显示字符串return"%s,%s"%(self.account.user_name,mobile)
通过ManyToManyField字段定义多对多关系(M:N)
fromdjango.dbimportmodelsclassAccount(models.model):#由于ManyToManyField定义在Contact,所以可以将Account看成主模型#操作举例:a1.contact_set.add(c1)a1.contact_set.remove(c1)user_name=models.CharField(max_length=80)password=models.CharField(max_length=)reg_date=models.DateField()def__unicode__():return"Account:%s"%self.user_nameclassContact(models.Model):#将Contact看成附模型,操作举例:c1.accounts.add(c1)accounts=models.ManyToManyField(Account)zip_code=models.CharField(max_length=10)address=models.CharField(max_length=80)mobile=models.CharField(max_length=20)def__unicode__(self):#定义模型显示字符串return"%s,%s"%(self.account.user_name,mobile)面向对象ORM抽象类继承:父类继承自models.Model(classMeta的absract属性置为True),但不会在底层数据库生成相应数据表,父类的属性列存储在其子类的数据表中
fromdjango.dbimportmodelsclassMessageBase(models.Model):f1=...f2=......classMeta:abstract=True#子类的数据表管理从父类继承的字段和自己定义的字段classMoment(MessageBase):headline=models.CharField(max_length=50)多表继承:子类直接继承父类,子类可以直接引用父类定义的字段,但父类的字段不会重复地在多个子类相关数据表中进行定义,Django内部通过在父模型和子模型之间建立一对一关系来实现多表继承,多表继承的每个模型类都在底层数据库生成相应的数据表管理数据
fromdjango.dbimportmodelsclassMessageBase(models.Model):f1=...f2=......#操作举例:m=Moment(**kwargs)#print(m1.messagebase.content)classMoment(MessageBase):headline=models.CharField(max_length=50)代理模型继承:父类用于在底层数据库管理数据表,子类(classMeta的proxy属性置为True)不定义数据列,只定义查询数据集的排列方式等元数据,使用代理模型继承的原因是子类中新的特性不会影响不会影响父类模型及其已有代码的行为
fromdjango.dbimportmodelsclassMessageBase(models.Model):f1=...f2=...pub_date=models.DateField()...#子类不定义数据列,只定义查询数据集的排列方式等元数据classOrderedMoment(MessageBase):classMeta:proxy=Trueordering=["-pub_date"]预览时标签不可点收录于话题#个上一篇下一篇