Django模型

一、model 文件中的类的建立:

对应的是数据库中的每个表,类中有什么字段,表就会对应的生成某个字段,主键id字段会自己生成;

数据库中的文件获取:只能通过模型类.objects来获取,不能通过模型类的实例获取;

对model中的代码进行增删改:先执行python manage.py makemigrations让修改动作保存到记录文件中,然后进行python manage.py migrate 让实际的操作应用到数据库中。

还有隐藏字段:_state 详情见https://www.liujiangblog.com/course/django/95第一章,模型和字段

__str__方法,用于返回实例对象的打印字符串;

get_abosolute_url()方法,返回每个模型实例的相应的访问url;
hash()方法,给模型实例提供唯一的哈希值,一旦生成就不允许修改

字段名:不能用,pass,两个下划线,下划线结尾

二、常用的Filed字段:

BooleanField:布尔类型,默认值时None,表单标签是checkboxinput,如果设置参数null=True,则表现为NullBooleanSelect选择框;

CharField:字符串类型,必须接收一个max_length参数,表单标签是text input;

DateField:日期类型,两个重要参数:(参数互斥,不能共存) auto_now:每当对象被保存时将字段设为当前日期,常用于保存最后修改时间。auto_now_add:每当对象被创建时,设为当前日期,常用于保存创建日期(注意,它是不可修改的)。设置上面两个参数就相当于给field添加了editable=False和blank=True属性。如果想具有修改属性,请用default参数。例子:pub_time = models.DateField(auto_now_add=True),自动添加发布时间。表单标签是DateInput;

DateTimeField:比上一个多了小时,分,秒的显示;

DecimalField:固定精度的十进制小数。相当于Python的Decimal实例,必须提供两个指定的参数!参数max_digits:最大的位数,必须大于或等于小数点位数 。decimal_places:小数点位数,精度。 当localize=False时,表单标签是NumberInput,否则是textInput类型。例子:储存最大不超过999,带有2位小数位精度的数,定义如下:models.DecimalField(..., max_digits=5, decimal_places=2);

EmailField:邮箱类型,默认max_length最大长度254位。使用这个字段的好处是,可以使用Django内置的EmailValidator进行邮箱格式合法性验证;

FileField:上传文件字段(不能设置主键),表单标签是ClearableFileInput标签;class FileField(upload_to=None, max_length=100, **options),upload_to用于设置上传地址的目录和文件名,也可以接收一个回调函数,该函数返回具体的路径字符串。回调函数中包含了instance参数和filename参数;

FilePathField:class FilePathField(path='', match=None, recursive=False, allow_files=True, allow_folders=False, max_length=100, **options);用来保存文件路径信息的字段;

ImageField:ImageField(upload_to=None, height_field=None, width_field=None, max_length=100, **options),同上,需提前安装pillow模块;这两个也需要在配置文件中,配置MEDIA_ROOT(上传文件在服务器的基本路径)和MEDIA_URL(指向上传文件的基本路径);假设你有一个ImageField字段,名叫mug_shot,那么在Django模板的HTML文件中,可以使用{{ object.mug_shot.url/size/name }}来获取该文件。其中的object用你具体的对象名称代替。

IntegerField:整数类型,表单标签是NumberInput或者TextInput;

GenericIPAddressField:class GenericIPAddressField(protocol='both', unpack_ipv4=False, **options),IPV4或者IPV6地址,字符串形式,例如192.0.2.30或者2a02:42fe::4。在HTML中表现为TextInput标签。参数protocol默认值为'both',可选'IPv4'或者'IPv6',表示你的IP地址类型。

TextField:用于储存大量的文本内容,表单标签是textarea;

URLField:一个用于保存URL地址的字符串类型,默认最大长度200;

UUIDField:用于保存通用唯一识别码(Universally Unique Identifier)的字段。注意不要写成default=uuid.uuid4()。

三、关系类型字段

外键要放在'多'的一方,对于关系字段,第一位置参数永远是关系对象,不能是verbose_name;

多对一:ForeignKey

其中on_delete后的参数

● CASCADE:模拟SQL语言中的ON DELETE CASCADE约束,将定义有外键的模型对象同时删除!

● 还有其他的参数,详情见https://www.liujiangblog.com/course/django/96,第一章,关系字段;

其中还有limit_choices_to等其他参数,详情见同上

多对多:ManyToManyField,只能选择一个模型设置该字段

里面有through参数,定义在

class Person(models.Model):

name = models.CharField(max_length=50)

class Group(models.Model):

name = models.CharField(max_length=128)

members = models.ManyToManyField(Person,

through='Membership', ## 自定义中间表

through_fields=('group', 'person'), )

class Membership(models.Model): # 这就是具体的中间表模型

group = models.ForeignKey(Group, on_delete=models.CASCADE)

person = models.ForeignKey(Person, on_delete=models.CASCADE)

inviter = models.ForeignKey(Person,on_delete=models.CASCADE,related_name="membership_invites", )

invite_reason = models.CharField(max_length=64)

定义了一个新的模型,用来保存Person和Group模型的多对多关系,并且同时增加了'邀请人'和'邀请原因'的字段。而且必须显式的指定through_fields参数,用于定义关系。through_fields参数指定从中间表模型Membership中选择哪两个字段,作为关系连接字段。

一对一:OneToOneField

四、创建表的时侯的模型元数据class Meta:

其下面的主要字段:

db_table,指定在数据库中,当前模型生成的数据表的表名;

ordering,排序,加'-'表示降序排列,不加则表示升序排列,可以在其后面再加字段,对什么进行排序;

idexes,接收一个应用在当前模型上的索引列表,models.Index(fields=['last_name', 'first_name']);

verbose_name,设置模型对象的名称。

五、模型的继承

1、想让抽象基类的子模型成为一个抽象基类,那必须显式的在该子模型的Meta中同样声明一个abstract=True;

2、在多表继承中,如不想让子类继承父类的ordering和get_latest_by参数,就必须在子类中显示的指出或重写;

3、声明一个代理模型只需在Meta中proxy的值设为True。

六、model的查询操作

1、创建对象:模型类的实例化构造,然后save( )方法保存;或者 类.objects.create( )方法创建

或者直接在模型类中增加create方法和自定义管理器并在其中添加创建对象的方法;

2、修改对象并保存:在其中千万不要忘记super().save( *args,**kwargs),这行确保了Django源码中关于save方法的代码会依然被执行。只有执行save方法后才会将数据写入数据库。

3、F表达式:entry = Entry.objects.get(name='刘江的博客')

>>> entry.number_of_pingbacks = F('number_of_pingbacks') + 1

>>> entry.save()

Django设计的这个F表达式在获取关联字段值的时候不用先去数据库中取值然后在Python内存里计算,而是直接在数据库中取值和计算,直接更新数据库,不需要在Python中操作,自然就不存在数据竞争和冲突问题了。

4、希望结果是哪个模型的实例,就用哪个,模型去调用;Blog.objects.xxx

5、QuerySet的切片:

Entry.objects.all()[:5] # 返回前5个对象

Entry.objects.all()[5:10] # 返回第6个到第10个对象

注意:不支持负索引!例如 Entry.objects.all()[-1]是不允许的

指定步长的时候,查询操作会立刻在数据库内执行,>>> Entry.objects.all()[:10:2]

6、字段查询:键名__字段=指定的内容

字段有:regex区分大小写的正则表达式匹配,iregex不区分大小写。。。等字段

7、Q对象

可以使用&或者|或~来组合Q对象,分别表示与、或、非逻辑。它将返回一个新的Q对象。

Q(question__startswith='Who')|Q(question__startswith='What')

这相当于:WHERE question LIKE 'Who%' OR question LIKE 'What%'

8、判断基于以下逻辑:

● 同一模型下,主键相等则实例相等

● 主键为None时,和任何实例都不相等

● 实例等于自己本身

● 代理模型的实例等于相同主键的父类实例

● 多表继承时,哪怕主键值相等,实例也不相等

七、不返回QuerySet的API

get() 获取单个对象,注意其查询的对象只能有一个,不然就报错;

create() 创建对象,无需save(),同时创建并且保存对象的方法;

get_or_create() 查询对象,如果没有找到就新建对象,建议只在post请求中这样使用,不然不安全;

update_or_create() 更新对象,如果没有找到就创建对象;

count() 统计对象的个数,永远不会引发异常;

latest() 获取最近的对象,其本质就是先排序,然后获取最前面的那个对象;

earliest() 获取最早的对象,获取最早先的对象;

first() 获取第一个对象,返回结果集的第一个对象,当没有找到好似就返回None;

last() 获取最后一个对象,返回结果集的最后一个对象;

aggregate() 聚合操作,见后面的章节;

exists() 判断queryset中是否有对象,查询其在不在;

update() 更新对象,对指定的字段执行更新操作,并返回匹配行数,

delete() 删除对象

八、注解与聚合

● aggregate: [ˈæɡrɪɡət ] ,聚合。做一些统计方面的工作。返回的是聚合后的数据字典;

● annotate: [ˈænəteɪt],注解。为返回的查询集添加一些额外的数据。返回的依然是查询集。

其中的Avg,Sum,Count,Max,Min等其他的聚合函数。

相关推荐
Auc2424 分钟前
使用scrapy框架爬取微博热搜榜
开发语言·python
中草药z25 分钟前
【Spring】深入解析 Spring 原理:Bean 的多方面剖析(源码阅读)
java·数据库·spring boot·spring·bean·源码阅读
地球资源数据云26 分钟前
全国30米分辨率逐年植被覆盖度(FVC)数据集
大数据·运维·服务器·数据库·均值算法
梦想画家40 分钟前
Python Polars快速入门指南:LazyFrames
python·数据分析·polars
程序猿000001号1 小时前
使用Python的Seaborn库进行数据可视化
开发语言·python·信息可视化
API快乐传递者1 小时前
Python爬虫获取淘宝详情接口详细解析
开发语言·爬虫·python
公众号Codewar原创作者1 小时前
R数据分析:工具变量回归的做法和解释,实例解析
开发语言·人工智能·python
Ahern_1 小时前
Oracle 普通表至分区表的分区交换
大数据·数据库·sql·oracle
FL16238631291 小时前
python版本的Selenium的下载及chrome环境搭建和简单使用
chrome·python·selenium
巫师不要去魔法部乱说1 小时前
PyCharm专项训练5 最短路径算法
python·算法·pycharm