经常使用字段及字段属性 |
int自增列,必须填入参数 primary_key=True。当model中若是没有自增列,则自动会建立一个列名为id的列。git
一个整数类型,范围在 -2147483648 to 2147483647。(通常不用它来存手机号(位数也不够),直接用字符串存,)sql
字符类型,必须提供max_length参数, max_length表示字符长度。数据库
这里须要知道的是Django中的CharField对应的MySQL数据库中的varchar类型,没有设置对应char类型的字段,可是Django容许咱们自定义新的字段,下面我来自定义对应于数据库的char类型django
自定义字段在实际项目应用中可能会常常用到,这里须要对他留个印象!app
from django.db import models # Create your models here. #Django中没有对应的char类型字段,可是咱们能够本身建立 class FixCharField(models.Field): ''' 自定义的char类型的字段类 ''' def __init__(self,max_length,*args,**kwargs): self.max_length=max_length super().__init__(max_length=max_length,*args,**kwargs) def db_type(self, connection): ''' 限定生成的数据库表字段类型char,长度为max_length指定的值 :param connection: :return: ''' return 'char(%s)'%self.max_length #应用上面自定义的char类型 class Class(models.Model): id=models.AutoField(primary_key=True) title=models.CharField(max_length=32) class_name=FixCharField(max_length=16) gender_choice=((1,'男'),(2,'女'),(3,'保密')) gender=models.SmallIntegerField(choices=gender_choice,default=3)
日期字段,日期格式 YYYY-MM-DD,至关于Python中的datetime.date()实例。ide
日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],至关于Python中的datetime.datetime()实例。测试
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 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) - 二进制类型
对应关系: '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)',
用于表示某个字段能够为空。spa
若是设置为unique=True 则该字段在此表中必须是惟一的 。3d
若是db_index=True 则表明着为此字段设置索引。code
为该字段设置默认值。
配置auto_now_add=True,建立数据记录的时候会把当前时间添加到数据库。
配置上auto_now=True,每次更新数据记录的时候会更新该字段。
foregnkey
外键类型在ORM中用来表示外键关联关系,通常把ForeignKey字段设置在 '一对多'中'多'的一方。
ForeignKey能够和其余表作关联关系同时也能够和自身作关联关系。注意:foregnkey字段不须要为
字段名添加__id,Django会自动添加。
设置要关联的表
设置要关联的表的字段
当删除关联表中的数据时,当前表与其关联的行的行为。
models.CASCADE
删除关联数据,与之关联也删除
是否在数据库中建立外键约束,默认为True。
def func():
return 10 class MyModel(models.Model): user = models.ForeignKey( to="User", to_field="id", on_delete=models.SET(func) )
OneToOneField
一对一字段。
一般一对一字段用来扩展已有字段。(通俗的说就是一我的的全部信息不是放在一张表里面的,简单的信息一张表,隐私的信息另外一张表,之间经过一对一外键关联)
设置要关联的表。
设置要关联的字段。
当删除关联表中的数据时,当前表与其关联的行的行为。(参考上面的例子)
在进行通常操做时先配置一下参数,使得咱们能够直接在Django页面中运行咱们的测试脚本
这样就能够直接运行你的test.py文件来运行测试
操做下面的操做以前,咱们实现建立好了数据表,这里主要演示下面的操做,再也不细讲建立准备过程
<1> all(): 查询全部结果
<2> filter(**kwargs): 它包含了与所给筛选条件相匹配的对象
<3> get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,若是符合筛选条件的对象超过一个或者没有都会抛出错误。
<4> exclude(**kwargs): 它包含了与所给筛选条件不匹配的对象
<5> values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后获得的并非一系列model的实例化对象,而是一个可迭代的字典序列
<6> values_list(*field): 它与values()很是类似,它返回的是一个元组序列,values返回的是一个字典序列
<7> order_by(*field): 对查询结果排序
<8> reverse(): 对查询结果反向排序,请注意reverse()一般只能在具备已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。
<9> distinct(): 从返回结果中剔除重复纪录(若是你查询跨越多个表,可能在计算QuerySet时获得重复的结果。此时可使用distinct(),注意只有在PostgreSQL中支持按字段去重。)
<10> count(): 返回数据库中匹配查询(QuerySet)的对象数量。
<12> last(): 返回最后一条记录
<13> exists(): 若是QuerySet包含数据,就返回True,不然返回False
Django测试准备工做
1 建立一个专门用于测试的文件,2 复制入口文件manage.py 中的下方代码,注意导入必须在main下方导入。
import os if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day58.settings") import django django.setup() from app01 import models
Django终端打印SQL语句
若是你想知道你对数据库进行操做时,Django内部究竟是怎么执行它的sql语句时能够加下面的配置来查看
在Django项目的settings.py文件中,在最后复制粘贴以下代码:
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }
数据增删改操做 |
单表操做:
# 新增数据 # 基于create建立 # user_obj = models.User.objects.create(name='tank',age=73,register_time='2019-2-14') # print(user_obj.register_time) # 基于对象的绑定方法建立 # user_obj = models.User(name='kevin',age=30,register_time='2019-1-1') # user_obj.save() # from datetime import datetime # ctime = datetime.now() # models.User.objects.create(name='egon', age=18, register_time=ctime)
# 修改数据 # 基于对象 # user_obj = models.User.objects.filter(name='jason').first() # user_obj.age = 17 # user_obj.save() # 基于queryset # models.User.objects.filter(name='kevin').update(age=66)
注意:filter()中多个键值对是and关系
# 删除数据 # 基于queryset # models.User.objects.filter(name='egon').delete() # 基于对象 # user_obj = models.User.objects.filter(name='owen').first() # user_obj.delete()
多表操做:
如何确立表关系:
一个A可否有多个B
一个B可否有对个A
若是二者都能那么就是 多对多
若是只有一方能够 一对多
若是双方都不能够可是二者却有关系 一对一
表关系:
一对一(OneToOneField):不管建在哪一方均可以,可是推荐建在查询频率较高的一方
一对多(ForeignKey):建在多的那一方
多对多(ManyToManyField):不管建在哪一方均可以,可是推荐建在查询频率较高的一方
外键字段的增删改查
一对多字段的增删改查(publish)
增
models.Book.objects.create(publish_id=1)
publish_obj = models.Publish.objects.filter(pk=1).first()
models.Book.objects.create(publish=publish_obj)
改
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.publish = new_publish_obj
book_obj = models.Book.objects.filter(pk=1).update(publish_id=2)
book_obj = models.Book.objects.filter(pk=1).update(publish=publish_obj)
删
删除书籍正常删除
删除出版社那么会级联删除改出版社对应的全部的书籍
多对多字段增删改查
增
add()
改
set()
删
remove()
# 上面三个方法均可以支持传多个数字或对象,set必须接收一个可迭代对象
清空
clear()
数据查询操做 |
正向查询与反向查询的概念
关联字段在你当前这表查询另外一张叫正向
关联字段不在你当前这表查询另外一张叫反向
总结:正向查询按字段,反向查询按表名小写
基于对象
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.publish.addr
book_obj.publish.name
book_obj.authors.all()
publish_obj = models.Publish.objects.filter(pk=1).first()
publish_obj.book_set.all()
基于双下划线的跨表查询
res = models.Book.objects.filter(publish__name='东方出版社',title='金梅').values('title','publish__name','authors__authordetail__phone')
聚合查询
aggregate
annotate(group by)
queryset对象.query也可以查看内部对应的sql语句
all()
filter()
values()
value_list()
order_by()
reverse()
distinct()
exclude()
count() 计数
exists() 布尔值
get() 数据对象自己
first()
last()
聚合查询 from django.db.models import Max,Min,Sum,Count,Avg aggragate() 分组查询(group by) annotate() group_concat() concat()