django学习の模型
orm:对象数据库和模型的映射。如果想以简单的方式去操作数据库,例如用类的方式去操作,就像 p = Person.get(id = 1),那么就必须使得代码和数据库的结构具有映射关系,实现这种关系,你可以事先就预先好一套创建类以及到数据库表的对应关系,也可以实时追踪数据库结构,很明显,第二张方式实现起来比较影响效率,所以大多数时候,在一开始,就用模型来对应数据库的一种关系,然后保证它们结构统一,就可以实现高度封装sql语句,用简洁明了的方式去操作业务逻辑,就像p = Person.get(id = 1),你就获得了数据库中person表的一个实例(信息)。当然,自己实现这样一个封装框架是比较复杂,django有强大的模型系统.
模型用类来表示数据库的表,每一个类属性是表中的一个字段,当然这个属性必须是django给出的field子类。先来做一个非常简单的模型。配置好django,创建好django项目以后。
#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=10)
sex = models.CharField(max_length=10)
这样,就得到了一个模型,这个模型会在数据库中创建一个user表,并且有一个name列,和sex列,他们都是varchar类型。modes提供了很多相应的field类型
CharField(max_lenght=10)中max_lenght是一个必须的字段,表示他的长度。如果需要一个无限长的较大文本,可以考虑用TextField,常用的字段有EmailField,
URLField,IPAddressField,BooleanField,NullBooleanField,FileField(保存文件),具体细节可以看官方文档,他们都是继承至Field类,在models块中。一般情况你可以用
IntegerField 表示数字,传入primary_key=True可以定义为主键
默认系统会自己生成主键。然后现在想写第二个类了,我们有了,User类,可以假设现在这一群User可能是几个团队的分子,并且一人只能参加一个团队,那么先得有个Team
类
#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=10)
sex = models.CharField(max_length=10) class Team(models.Model):
name = models.CharField(max_length=10)
这样就多了一个Team类,按一开始的设定要用到一对多的关系外键,所以要用ForeignKey(Team),像这样
#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=10)
sex = models.CharField(max_length=10)
team = models.ForeignKey(Team) class Team(models.Model):
name = models.CharField(max_length=10)
但是如果现在同步会出错,因为Team在User下面,解释时还没有,会报错,一般输入python manage.py makemigrations创建一个历史迁移文件,然后migrate执行迁移,就会同步到数据库.为了不报错,应该是这样:
#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here. class Team(models.Model):
name = models.CharField(max_length=10) class User(models.Model):
name = models.CharField(max_length=10)
sex = models.CharField(max_length=10)
team = models.ForeignKey(Team)
这个时候,user这个群体可能是好友,好友的关系是多对多,一个人可能有很多好友,并且每个好友也有很多好友,所以有多对多的关系,如下:
#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=10)
sex = models.CharField(max_length=10)
team = models.ForeignKey(Team)
friend = models.ManyToManyField('self') class Team(models.Model):
name = models.CharField(max_length=10)
'self'表示是自己,如果是Team传入类变量即可,同样适用于外键。django默认表示如果你是我好友,那我也是你好友,用symmetrical = False参数可以打破这种对称,如果需要可以用在ManyToManyField。
如果有的Team比较特殊,他们不仅有名字,还有特别的字段,比如坦克,但是它们又是Team,可以用继承,也可以用OneToOneField(Team).用继承如下:
#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=10)
sex = models.CharField(max_length=10)
team = models.ForeignKey(Team)
friend = models.ManyToManyField('self') class Team(models.Model):
name = models.CharField(max_length=10) class SuperTeam(Team):
tank = models.CharField(max_length=10)
这样可能看不出用继承有什么优势,如果Team类有一万个属性,而SuperTeam有一万零一,前一万个和Team一样,就可以用继承。
有时候继承可能不需要Team,就是实际上Team用不到,那么可以把Team设置成抽象继承类,数据库就不会创建这张表,它只是为了继承而存在的,在Team的Meta嵌套类里面
定义abstruct = True,就像这样:
#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=10)
sex = models.CharField(max_length=10)
team = models.ForeignKey(Team)
friend = models.ManyToManyField('self') class Team(models.Model):
name = models.CharField(max_length=10)
class Meta:
abstract = True class SuperTeam(Team):
tank = models.CharField(max_length=10)
嵌套类细节可参考官方文档
多对多关系实际上是在数据库建立第三张表来保存这种关系,有时候如果希望这张表也有字段,那就可以自己来写这张表,比如User成为好友的时间。
#-*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils import timezone
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=10)
sex = models.CharField(max_length=10)
team = models.ForeignKey(Team)
friend = models.ManyToManyField('self',through='FriendShip') class Team(models.Model):
name = models.CharField(max_length=10)
class Meta:
abstract = True class SuperTeam(Team):
tank = models.CharField(max_length=10) class FriendShip(models.Model):
user = models.ForeignKey(User)
friend = models.ForeignKey(User)
data_became_friend = models.DateTimeField(default=timezone.now)
先通过through指定想成为好友关系的表,然后第三种表中定义这种关系,如果是不同类之间的多对多,那么也一样,只是有一个外键指向另一张成为好友的表就行了,然而这里面有个矛盾,假如关系表里面外键User,像这个例子,多于三个,像这样
class FriendShip(models.Model):
user = models.ForeignKey(User,relat_name = 'user_set')
friend = models.ForeignKey(User)
three = models.ForeignKey(User)
data_became_friend = models.DateTimeField(default=timezone.now)
django并没有智能到可以分辨哪一个字段是他想要对应的,因为本来是两者的好友关系,莫名其妙多了第三种,这时候需要在外键里面加入through_fields = ('user','friend')参数,同理如果是不同类的多对多,也应该按顺序写参数。
至于操作,django提供了manage,和QuerySet,这都是什么鬼啊。
而objects就是每个类只想manage的变量,manage获得,提供了all filter exclude get 方法,返回Queryset对象,Queryset本身也提供了manage的方法,所以最后是支持连缀操作的,就像,get(id =1).filter(name__contains = "Tree"),django也提供了很多像__contains这样的过滤操作,只需名字__contains就可以了。修改有update,或者直接属性赋值修改,这种修改把没有修改的值也修改一遍,按照原来的值。最后save函数会把结果在数据库执行,这是一种惰性机制,我并不会第一时间的执行。
创建:
创建实例有两种方法,一种是惰性的,比如需要一个user对象,只需要:索隆 = User(name = ‘索隆’,sex='男',),然后调用索隆.save()保存.
一种是直接 索隆.objects.create(.....)创建。
对于普通多对多还有,如索隆.friendship.create(name = '路飞')或者 索隆.friendship.add(实例对象)来创建对象或添加对象,并且django会做好所有事情,然而对于上面提到的自定义的多对多关系表则不行,因为既然你用到了自定义关系表,很大意义上是因为你需要额外的字段,如果这样创建,那么django根本不能知道你想为额外的字段添加什么,
在这种情况下,唯一办法就是先创建好两个实例,如:a = User.objects.create(....),b=User.objects.create(....),然后Friendship.objects.add(a,b,额外字段=好)这样创建。
获取:
基于manage的方法,一般是对象.objects.方法()获取。
get(),获得单一对象。
filter(),过滤器,获得一个queryset
all(),如其名,获得所有对象。
order_by('字段'),按字段排序
exclude(),和filter相反,获得filter的补集
返回的queryset是支持切片操作的,同时queryset也支持了filter和exclude以及order_by更多额外的方法。
还有查询字段时,通过 字段名__contains = 'ssss'可以改变查询方式,默认是__exact精准查询。
__contains: 即使sql的like
__icontains:忽略大小写
__gt : 大写
__gte : 大于等于
__lt : 小于
__lte : 小于等于
__in : 在list范围内
__startswith 和 __istartswith:以什么开头
__endswith __iendswith:结尾
__range:范围
__year,__month,__day
__isnull.
Q对象:
django.db.models里面的Q对象,用Q对象包裹以后参数就可以用| & ~来查询,如get(Q(name__contains='sss')|Q(,,,,)).
django学习の模型的更多相关文章
- [Django学习]模型
ORM简介 MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库 ORM是“对象-关系-映射”的简称 ...
- 5.django学习模型
##Django Models ##编写models 1.在应用根目录下创建models.py并引入models模块,创建类,继承models.Model该类即是一张数据表 2.字段创建 ##映射数据 ...
- Django学习笔记(2)——模型,后台管理和视图的学习
一:Web投票示例 本节我们首先从全局范围再复习一下Django的概念,让自己对Django的设计理念, 功能模块,体系架构,基本用法有初步的印象. Django初始的详细博客内容:请点击我 该应用包 ...
- Python Django 学习 (二) 【Django 模型】
注: 由于自己排版确实很难看,本文开始使用markdown编辑,希望有所改善 官方定义 A model is the single, definitive source of information ...
- Django学习笔记(16)——扩展Django自带User模型,实现用户注册与登录
一,项目题目:扩展Django自带User模型,实现用户注册与登录 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册,登录,用户认证,注销,修改密码等功能. ...
- django学习-数据库配置-创建模型
数据库配置 在mysite/settings.py中,包含了django项目设置的python模块 通常,这个配置文件使用SQLite作为默认数据库.如果你不熟悉数据库,或者只是想尝试下django, ...
- Django学习笔记之数据库-模型的操作
模型的操作 在ORM框架中,所有模型相关的操作,比如添加/删除等.其实都是映射到数据库中一条数据的操作.因此模型操作也就是数据库表中数据的操作. 添加模型 添加模型到数据库中.首先需要创建一个模型.创 ...
- Django 学习第六天——Django模型基础第一节
一.Django 的 ORM 简介: Django的ORM系统的分析: 1.ORM 概念:对象关系映射(Object Relational Mapping,简称ORM) 2.ORM的优势:不用直接编写 ...
- django学习笔记(三)模型
1.创建一个django app: python manage.py startapp books 2.validate 命令检查你的模型的语法和逻辑是否正确.一旦你觉得你的模型可能有问题,运行 py ...
随机推荐
- 关于C语言链表的学习
今天讲了一种非传统型的链表.听得不是太好. 到数据结构那一部分的时候.一定要好好听听.
- Android -- 背景虚化
1,在项目中我们常有这样的需求,就是在个人中心的时候,当用户登录后,要显示用户登陆后的头像,然后背景是用户头像的虚化 ,接下来就来实现一下这个功能,先看一下效果 2,实现起来也挺简单的,没什么难度 , ...
- java 枚举类小结 Enum
好久没有接触枚举类了,差不多都忘了,今天抽出个时间总结一下吧.说实话,枚举类确实能够给我们带来很大的方便. 说明:枚举类它约定了一个范围,可以理解成只可以生成固定的几个对象让外界去调用,故枚举类中的构 ...
- BJFU 1009
描述 现在社会上的抽奖活动简直是太多了.前段时间中国联通就举办了一个很无聊的抽奖活动,规则是每人可以向中国联通的短信系统发送一个实数,系统每天会从这些数字中选择一个无重复(就是有且只有一个)且最小的数 ...
- 夺命雷公狗---node.js---9实现页面的跳转
废话不多说,我们先来看看项目的文件结构,如下所示: 然后我们创建一个index.js的文件让他来做端口监听,代码如下所示: var http = require('http'); var fs = r ...
- linux下的终端模拟器urxvt的配置
内容所在的文件: ~/.Xdefaults 文件的内容: URxvt.background:[90]#000000URxvt.foreground:#ffffffURxvt.colorBD:Gray9 ...
- SqlServer:此数据库处于单用户模式,导致数据库无法删除的处理
此数据库处理单用户模式,尚在连接当中,无法删除(既使将SQLServer停止后再启动也是如此) USE [master] GO /****** Object: StoredProcedure [dbo ...
- SSAS维度上有多个表的注意事项
在Sql Server Analysis Service中维度上有多张表(大于一张表)时,一定要注意将第二张表开始用到维度属性中的KeyColumns下的NullProcessing要设置为Unkno ...
- 在线白板,基于socket.io的多人在线协作工具
首发:个人博客,更新&纠错&回复 是昨天这篇博文留的尾巴,socket.io库的使用练习,成品地址在这里. 代码已经上传到github,传送门.可以开俩浏览器看效果. 现实意义是俩人在 ...
- UINavigationController(转)
UINavigationController是IOS编程中比较常用的一种容器view controller,很多系统的控件(如UIImagePickerViewController)以及很多有名的AP ...