diango-models
Administrator
2018-04-20
常用的字段类型 表间关系 元选项 模型成员 创建对象 模型查询(数据查询) 字段选项 AutoField CharField(max_length=) TextField IntegerField DecimalField(max_digits=none, decimal_places=None) 生成一个自动增长的 IntegerField ,且具有唯一性,常用来设置主键 字符串类型,max_length用来指定字符串的最大长度 当字符大于4000时使用,显示时是以文本域的格式显示 int 型 float 型 max_digits 表示小数总位数 ,decimal_places 表示小数点后的位数 FloatField BooleanField 定义float 型 ,但是不用指定小数位数等,使用较方便 布尔类型 ,只有两个值TRUE/FALSE NullBooleanField DateField([auto_now=false, auto_now_add=false]) TimeField 布尔类型 ,但是有三个值 ,TRUE/FALSE/null 日期类型 参数说明 auto_false: auto_now_add: 当该值为真时,会自动设置该字段为最后一次的修改时间 当该值为真时,会自动设置该字段为创建时间 两个参数默认值为FALSE,且可以省略 时间类型 参数同DateField DateTimeField 日期时间类型 参数同DateField 这两个参数以及default是不能同时使用的 FileField ImageField 一个上传文字的字段 一个上传image的字段 所谓的字段选项,即对于字段类型的约束,填入字段类型的()中 null blanke db_column: 如果为True,如果该字段没有填入参数,则将null存到数据库中,默认值为false code: name = ChraField(null = True) 如果为True, 则允许该字段为空,默认为flase 指定字段的名称,如果未指定则为属性的名称 db_index default 若值为True,则表中会为此字段创建索引 创建默认值 primary_key unique 若为True,则将该字段设置为主键 如果为True,这个字段在表中具有唯一值 一对多 用一访问多 访问id ForeignKey 将主键设置在多的端中 格式 : 对象.模型类小写_set.all()/get(条件) code: grade.studengts_set.all() 格式 code: 对象.属性_id studengs.sgrade_id 所谓的元选项,是在模型类下面定义的一个Mate类,它常用来设置一些附加信息 db_table = '' 用来设置表的名字,默认为应用名_类名 ordering = ['属性'] 用来设置排序方式 '-属性'表示降序 附: 排序是要消耗数据库的资源 code: class Meta: db_table = '学生' Meta类应放在需要指定名称的类的下面 类属性 自定义管理器manager类 子主题 管理器 objects 管理器是可以自定义的,当我们没有自定义管理器是,django默认自动生成objects这个管理器 如何自定义 objects是manage.py下的一个方法,他可以让我们与数据库进行交互 自定义较简单,只需要在需要管理的模型类下面加上代码: 管理器名 = models.Manager()即可 code:class achievement(models.Model): """docstring for achievement""" newobjects = models.Manager() grade = models.IntegerField(default=1501021) name = models.CharField(max_length=20) 附:当我们自定义了管理器以后,那么django就不会创建objects这个管理器了 manager这个管理器类是django用来同数据库进行交互的接口,但是其范围较广,针对性差,所以我们可以通过自定义这个管理器类来达到具体的针对效果 作用: 默认存在方法 :get_queryset() ,所以我们要添加约束,也就是在这个方法的基础上在进行约束 方法: 可以在其中添加附加方法 修改原始返回集,也就是对原始返回集加上一些约束,使返回结果达到具体要求 需要重新定义一个类,该类继承于models.Manager ,且类名为新的管理器名,该类的作用是修改get_queryset()这个方法 code: class newmanager(models.Manager): """docstring for newmanager""" def get_queryset(self): return super(newmanager, self).get_queryset().filter(subject1=85) 需要注意的是:filter这个过滤器在这个方法中的筛选条件只能是以 = 来判断,不能有> <等 自定义管理器类过后,如果要使用该管理器类,需要定义一个管理器,当与数据库进行交互时,需要使用该管理器才能使其起作用 code: newobjects = newmanager() 但是不同于管理器,自定义管理器类后,原来的manager还可以继续使用 以前创建对象(即表中的一条数据)的方法都是通过在shell环境下对模型类进行实例化来完成的,但是我们可以定义方法来创建对象 创建对象的方法又分为两种 定义一个模型类方法来完成 在自定义的管理器类中添加方法 code: @classmethod def createach(cls, name, num, go_num, practice, subject1, subject2, subject3, subject4, subject5, subject6, subject7, subject8, subject9, ranking): stu = cls(name = name, num = num, go_num = go_num, practice = practice, subject1 = subject1, subject2 = subject2, subject3 = subject3, subject4 = subject4, subject5 = subject5, subject6 = subject6, subject7 = subject7, subject8 = subject8, subject9 = subject9, ranking = ranking) return stu 注意该方法是属于模型类的一个类方法,而修饰器的作用就是制定该方法是一个类方法 保存数据可以在调用这个方法后执行 由于默认的查询结果为数据库中的所有数据,我们需要对原始的查询集进行过滤,一个查询集可以有多个过滤器 过滤器 返回单个数据 限制查询集 相当于spl语句中的 * 为原始集,返回所有数据,但是我们可以通过类似where这样的方法去过滤 返回查询集结果的一系列方法称为过滤器 all filter() 特殊的一种过滤器,不能添加过滤条件 filter(键=值,键=值) filter(键=值).filter(键=值) 返回符合条件的数据 需要注意的是filter的关系运算符只能用 = ,不能用其余的关系运算符,不然会报错 exclude() order_by() 使用格式同filter 过滤掉符合条件的数据,作用与filter相反 作用是对指定字段进行排序,字段给出的方式为'字段名' 方式 code: achievement.newobjects.all().filter(subject4=74) code : achievement.newobjects.all().exclude(subject4=85) '字段名' '字段名' 升序 降序 code : achievement.newobjects.all().order_by('-subject4') values() 上面的过滤方法,如果不在模型类中加入方法__str__,则返回值均是一个类,而values()的作用就是将类中的所有符合条件的值以字典的形式返回,key为对应的字段 使用的方法也同所有的过滤器一样,只要在前一个过滤器后 .新过滤器即可 code: achievement.newobjects.all().values().filter(subject4=85) get() count() 返回满足条件的单个对象,条件写在()中,可以同时有多个条件,用,隔开,是且关系,但是不能有多个多个对象放回,否则会报Multiple Objects Returned(多个对象被返回的错),而且get()后不能再添加过滤器 code: achievement.newobjects.get(subject1=85,subject4=85) 返回当前查询集的对象的个数 code: achievement.newobjects.all().filter(subject4=85).count() first() last() exists() 返回当前查询集的第一个对象 code: achievement.newobjects.all().first() 返回当前查询集的最后一个对象 code: achievement.newobjects.all().last() 判断当前查询集是否有数据,有则放回True,否则返回False code: >>> achievement.newobjects.all().exists() True >>> achievement.newobjects.all().filter(subject4=89).exists() False 当数据较多时,我们可以通过下标的方式来对查询集进行限制 code: achievement.newobjects.all()[1:3] 字段查询 查询集的缓存 django对数据库的访问采用了缓存的方法,即当我们查询了相应的数据库时,django会把数据缓存到内存中,当我们再次查询时,直接从内存中提取数据,使得速度大大提升了 前面的过滤器只能实现一些较简单的逻辑运算,对于其他逻辑运算就要用这个字段查询来实现 contains(字段__contains(条件)) startswith(字段__startswitch(条件))、 endswith 返回对应字段包含条件的对象 code: achievement.new1.all().filter(name__contains='黄') 大小写敏感 以条件开头或者结束 code: achievement.new1.filter(name__startswith='黄',name__endswith='杨') 以上的过滤器均是区分大小写的,但是在前面加上一个i则不区分 code: icontains() isnull 、 isnotnull in 判断是否为空 achievement.new1.filter(name__isnull=False) 返回包含在指定值里的对象 code: achievement.new1.filter(pk__in=[1, 5, 6]) 比较运算符 gt gte lt lte 大于 code: achievement.new1.filter(subject4__gt=80) 大于等于 小于 小于等于 逻辑或运算 上面在filter这个过滤器中加的各种约束条件之间的关系是and的关系,但是有时又需要一些逻辑或运算,这是就要用到这里介绍的Q对象 Q对象 Q对象可以实现or查询 code: achievement.new1.filter(Q(subject4=85)|Q(subject4=74)) 要使用Q对象,首先需要引入Q方法 code: from django.db.models import Q 当只有一个Q对象时,和没有Q对象的结果相同,但是可以使用在Q对象前面加上一个 ~ 来实现取反操作 code: achievement.new1.filter(~Q(subject4__lt=85)) F对象 可以比较一个模型类中A属性和B属性 也要先引入F对象 code: from django.db.models import F code: achievement.new1.filter(subject6__gt=F('subject5')) 说明,返回subject6>subject5的对象 编码格式导致的错误 错误提示: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128) 原因:这是由于Python默认的编码格式是ascii码,而网页一般使用的编码格式是utf-8,所以会存在编码格式的差别 有两种解决方法: 一个解决的方案在程序中加入以下代码: Python代码 import sys reload(sys) sys.setdefaultencoding('utf8') 另一个方案是在python的Lib\site-packages文件夹下新建一个sitecustomize.py,内容为: Python代码 # encoding=utf8 import sys reload(sys) sys.setdefaultencoding('utf8') 此时重启python解释器,执行sys.getdefaultencoding(),发现编码已经被设置为utf8的了,多次重启之后,效果相同,这是因为系统在python启动的时候,自行调用该文件,设置系统的默认编码,而不需要每次都手动的加上解决代码,属于一劳永逸的解决方法。 查询系统默认编码可以在解释器中输入以下命令: Python代码 >>>sys.getdefaultencoding() 设置默认编码时使用: Python代码 >>>sys.setdefaultencoding('utf8') 可能会报AttributeError: 'module' object has no attribute 'setdefaultencoding'的错误,执行reload(sys),在执行以上命令就可以顺利通过。 此时在执行sys.getdefaultencoding()就会发现编码已经被设置为utf8的了,但是在解释器里修改的编码只能保证当次有效,在重启解释器后,会发现,编码又被重置为默认的ascii了,那么有没有办法一次性修改程序或系统的默认编码呢。 models