Django Model操作

1. 创建Model类:

from django.db import models
#创建普通字段
class User(models.Model):
	user = Charfield( 各种参数,包括是否为空,类型,长度,索引等等 )

各种字段类型:

AutoField(Field)
- int自增列,必须填入参数 primary_key=True

BigAutoField(AutoField)
- bigint自增列,必须填入参数 primary_key=True

注:当model中如果没有自增列,则自动会创建一个列名为id的列
from django.db import models

class UserInfo(models.Model):
    # 自动创建一个列名为id的且为自增的整数列
    username = models.CharField(max_length=32)

class Group(models.Model):
    # 自定义自增列
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)

SmallIntegerField(IntegerField):
- 小整数 -32768 ~ 32767

PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正小整数 0 ~ 32767 IntegerField(Field)
- 整数列(有符号的) -2147483648 ~ 2147483647

PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
- 正整数 0 ~ 2147483647

BigIntegerField(IntegerField):
- 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807

自定义无符号整数字段

class UnsignedIntegerField(models.IntegerField):
    def db_type(self, connection):
        return 'integer UNSIGNED'

PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
    'AutoField': 'integer AUTO_INCREMENT',
    'BigAutoField': 'bigint AUTO_INCREMENT',
    'BinaryField': 'longblob',
    'BooleanField': 'bool',
    'CharField': 'varchar(%(max_length)s)',
    'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
    'DateField': 'date',
    'DateTimeField': 'datetime',
    'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
    'DurationField': 'bigint',
    'FileField': 'varchar(%(max_length)s)',
    'FilePathField': 'varchar(%(max_length)s)',
    'FloatField': 'double precision',
    'IntegerField': 'integer',
    'BigIntegerField': 'bigint',
    'IPAddressField': 'char(15)',
    'GenericIPAddressField': 'char(39)',
    'NullBooleanField': 'bool',
    'OneToOneField': 'integer',
    'PositiveIntegerField': 'integer UNSIGNED',
    'PositiveSmallIntegerField': 'smallint UNSIGNED',
    'SlugField': 'varchar(%(max_length)s)',
    'SmallIntegerField': 'smallint',
    'TextField': 'longtext',
    'TimeField': 'time',
    'UUIDField': 'char(32)',

BooleanField(Field)
- 布尔值类型

NullBooleanField(Field):
- 可以为空的布尔值

CharField(Field)
- 字符类型
- 必须提供max_length参数, max_length表示字符长度

TextField(Field)
- 文本类型

EmailField(CharField):
- 字符串类型,Django Admin以及ModelForm中提供验证机制

IPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制

GenericIPAddressField(Field)
- 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
- 参数:
protocol,用于指定Ipv4或Ipv6, ‘both’,“ipv4”,“ipv6”
unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol=“both”

URLField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证 URL

SlugField(CharField)
- 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)

CommaSeparatedIntegerField(CharField)
- 字符串类型,格式必须为逗号分割的数字

UUIDField(Field)
- 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证

FilePathField(Field)
- 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
- 参数:
path, 文件夹路径
match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件
allow_folders=False, 允许文件夹

FileField(Field)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = “” 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage

ImageField(FileField)
- 字符串,路径保存在数据库,文件上传到指定目录
- 参数:
upload_to = “” 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名(字符串)
height_field=None 上传图片的宽度保存的数据库字段名(字符串)

DateTimeField(DateField)
- 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]

DateField(DateTimeCheckMixin, Field)
- 日期格式 YYYY-MM-DD

TimeField(DateTimeCheckMixin, Field)
- 时间格式 HH:MM[:ss[.uuuuuu]]

DurationField(Field)
- 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型

FloatField(Field)
- 浮点型

DecimalField(Field)(这个字段实际上是已字符串的形式进行存储的,所以精确)
- 10进制小数
- 参数:
max_digits,小数总长度
decimal_places,小数位长度

BinaryField(Field)
- 二进制类型字段

字段里的参数:

可选参数说明
null如果True,Django将NULL在数据库中存储空值。默认是False。不要在字符串字段上使用。null是数据库范畴的概念
blank如果True,该字段允许为空。默认是False。同null不同, 如果字段有blank=True,则表单验证将允许输入空值。如果字段有blank=False,则需要该字段。
db_column用于此字段的数据库列的名称。如果没有给出,Django将使用该字段的名称。
db_index如果True,将为此字段创建数据库常规索引。
unique如果True,该字段在整个表格中必须是唯一的。
primary_key如果True,此字段是模型的主键。
default默认值 当前字段如果不给值则执行默认值

有些字段是配合django的admin中进行操作,如果不用admin,那么设置将没有意义。而且以上这些字段和参数是针对普通的字段,当我们进行特殊字段的时候,又要注意一些东西。特殊字段指的:

一对一 models.OneToOneField(其他表)

一对一的字段继承自ForeignKey,所以本质上,是设置ForeignKey。

一对多(外键)models.ForeignKey(其他表)

外键的主要参数:
to ,关联到什么表
to_field,关联到对应表的什么字段(默认是id)
on_delete,在django2.0之后,这个字段是在设置一对多是必须要填的参数,一般设置为models.CASCADE(在删除外键后,对应的数据也删除)

多对多 models.ManyToManyField(其他表)

创建多对多除了有Django默认的.ManyToManyField(方法,还可以自己创建,这2个方法的优缺点:
如果用默认的字段创建,那么第三个表中只会有3个默认字段(不可更改名字),自增id,两外2个表关联的id,但是方便操作,对后续的操作比较方便,例如add,set,remove方法。如果自己创建,那么可以自定义字段,但是创建繁琐,可能会出现问题

创建2个字段
class Tag(models.Model):
    name = models.CharField(max_length=32)
   
class User(models.Model):
    name = models.CharField(
        max_length=32,
        null=False,
    )

方法一:

class User(models.Model):
    name = models.CharField(
        max_length=32,
        null=False,
    )
    ut = models.ManyToManyField('Tag')
    

方法二:

class UserToTag(models.Model):
    u_id = models.ForeignKey('User',on_delete=models.CASCADE)
    t_id = models.ForeignKey('Tag', on_delete=models.CASCADE)
    第三章表中可以自己添加有需要的字段
    time = models.DateTimeField()
	
    #(联合唯一)
    class Meta:
        unique_together=[
            ('u_id','t_id',),
        ]

还有一种特殊方法,不推荐使用:

class User(models.Model):
    name = models.CharField(
        max_length=32,
        null=False,
    )
    #to,要关联的表,through,通过哪个第三章表;through_fields,通过第三章表中的哪些字段
    ut = models.ManyToManyField( to = 'Tag',
    through = 'UserToTag' ,
    through_fields = [ 'u_id','t_id'])
    
class UserToTag(models.Model):
    u_id = models.ForeignKey('User',on_delete=models.CASCADE)
    t_id = models.ForeignKey('Tag', on_delete=models.CASCADE)
    第三章表中可以自己添加有需要的字段
    time = models.DateTimeField()
	
    #(联合唯一)
    class Meta:
        unique_together=[
            ('u_id','t_id',),
        ]

自关联:

一种特殊的多对多类型,实现自己对自己的关联,实际情况应用:互粉,互相添加关注

 models.ManyToManyField(self/自己的表名 , related_name(别名,推荐加上,当进行反向操作时很方便))

需要掌握的东西:

  1. 索引
  2. 一对多:on_delete
  3. 一对多和一对一的关系:在一对一的字段中,多包含了一个字段:unique:True(唯一)
  4. 多对多的创建,和各种类型

PS.related_name是有必要的,以后方便操作

2 . 操作创建的类:

参考资料
在查询和操作数据库数据时,主要就是在操作QuerySet对象,QuerySet 可以被构造,过滤,切片,做为参数传递,这些行为都不会对数据库进行操作。只要你查询的时候才真正的操作数据库。
下面的 QuerySet 行为会导致执行查询的操作:

循环(Iteration):QuerySet 是可迭代的,在你遍历对象时就会执行数据库操作。例如,打印出所有博文的大标题:

for e in Entry.objects.all():
    print(e.headline)

切片(Slicing): QuerySet 是可以用 Python 的数组切片语法完成切片。一般来说对一个未查询的 QuerySet 切片就返回另一个未查询的 QuerySet (新 QuerySet 不会被执行)。不过如果你在切片时使用了 “step” 参数,Django 仍会执行数据库操作并且返回列表对象。对一个查询过的QuerySet执行切片也会返回列表对象。

序列化/缓存化(Pickling/Caching): 详情请查看 pickling QuerySets。 这一节所强调的一点是查询结果是从数据库中读取的。

repr(). 调用 QuerySet 的 repr() 方法时,查询就会被运行。这对于 Python 命令行来说非常方便,你可以使用 API 立即看到查询结果。

len(). 调用 QuerySet 的 len() 方法,查询就会被运行。这正如你所料,会返回查询结果列表的长度。

注意:如果你想得到集合中记录的数量,就不要使用 QuerySet 的 len() 方法。因为直接在数据库层面使用 SQL 的 SELECT COUNT(*) 会更加高效,Django 提供了 count() 方法就是这个原因。详情参阅下面的 count() 方法。

list(). 对 QuerySet 应用 list() 方法,就会运行查询。例如:

1
entry_list = list(Entry.objects.all())
要注意地是:使用这个方法会占用大量内存,因为 Django 将列表内容都载入到内存中。做为对比,遍历 QuerySet 是从数据库读取数据,仅在使用某个对象时才将其载入到内容中。

Pickling QuerySets

如果你要 序列化(pickle) 一个 QuerySet,Django 首先就会将查询对象载入到内存中以完成序列化,这样你就可以第一时间使用对象(直接从数据库中读取数据需要一定时间,这正是缓存所想避免的)。而序列化是缓存化的先行工作,所以在缓存查询时,首先就会进行序列化工作。这意味着当你反序列化 QuerySet 时,第一时间就会从内存中获得查询的结果,而不是从数据库中查找。

如果你只是想序列化部分必要的信息以便晚些时候可以从数据库中重建 Queryset ,那只序列化 QuerySet 的 query 属性即可。接下来你就可以使用下面的代码重建原来的 QuerySet (这当中没有数据库读取):

import pickle
query = pickle.loads(s)     # Assuming 's' is the pickled string.
 qs = MyModel.objects.all()
qs.query = query            # Restore the original 'query'.

query 属性是一个不透明的对象。这就意味着它的内部结构并不是公开的。即便如此,对于本节提到的序列化和反序列化来说,它仍是安全和被完全支持的。

方法:
QuerySet
QuerySet API

返回新的Querysets对象的方法:

  • filter() | exclude() | annotate() | order_by() 排序,如果在表前面加"-"说明反向排序,相当于reverse() | reverse() | distinct() 去重 (一般不加参数)
    values() | values_list() | dates() | datetimes() | none() | all() | union()
    intersection() | difference() | select_related() 提高对有外键字段的查询效率| prefetch_related()
    extra()添加子查询,可以自己创建自己需要的SQL语句 | defer(列名) 除了某列数据的所有数据 | only(列名) 只读取某列数据 | using() | select_for_update() | raw()

添加条件

  • AND (&) | OR (|)

不会返回Queryset对象的方法:

  • get() | create() | get_or_create() | update_or_create() | bulk_create()
    bulk_update() | count() | in_bulk() | iterator() | With server-side cursors
    Without server-side | cursors latest() | earliest() | first() | last()
    aggregate() | exists() | update() | delete() | as_manager() | explain()

条件查询:

  • exact | iexact | contains | icontains | in | gt | gte | lt | lte | startswith
    istartswith | endswith | iendswith | range | date | year | iso_year | month | day
    week | week_day | quarter | time | hour | minute | second | isnull | regex | iregex

聚合函数:

  • expressions | output_field | filter
    **extra | Avg | Count | Max | Min | StdDev | Sum | Variance

数据关联工具

  • Q() objects | Prefetch() objects | prefetch_related_objects() |
    FilteredRelation() objects
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值