class Person(models.Model):
pid = models.AutoField(primary_key=True) # 主键
name = models.CharField(max_length=32) # varchar(32)
age = models.IntegerField() # 整型 -21亿-21亿
# birth = models.DateTimeField(auto_now_add=True) # 每当新增数据时 自动保存当前时间
birth = models.DateTimeField(auto_now=True) # 每当新增和编辑数据时 自动保存当前时间
字段类型
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)
- 二进制类型
使用Django的admin创建超级用户
D:\python\orm_base>python manage.py createsuperuser
Username (leave blank to use 'xiefei'): root1234
Email address:
Password:
Password (again):
The password is too similar to the username.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.
urls.py中包含
urlpatterns = [
path('admin/', admin.site.urls),
]
setting.py中包含
INSTALLED_APPS = [
'django.contrib.admin', # 必须有
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config'
]
然后再网页访问
- http://127.0.0.1:8000/admin/
在app下的admin.py下注册model
from django.contrib import admin
from app01 import models
# Register your models here.
admin.site.register(models.Person)
未定义__str__(self):
定义__str__(self):后
class Person(models.Model):
pid = models.AutoField(primary_key=True) # 主键
name = models.CharField(max_length=32) # varchar(32)
age = models.IntegerField() # 整型
# birth = models.DateTimeField(auto_now_add=True) # 每当新增数据时 自动保存当前时间
birth = models.DateTimeField(auto_now=True) # 每当新增和编辑数据时 自动保存当前时间
def __str__(self):
return "{}-{}".format(self.name, self.age)
- 用python脚本执行数据库相关炒作操作
- 创建一个orm操作的文件夹
- 创建python文件
- 从manage.py中导入系统环境配置文件设置环境配置变量
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'orm_base.settings')
# !/usr/bin/env python
# -*- coding: UTF-8 -*-
# 作者 :xiefei
# 时间 :2020/8/2 12:05
# IDE :PyCharm
import os
if __name__ == '__main__':
# 下面的 cms_book 改成你当前的项目名称
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "orm_base.settings")
import django
django.setup()
from app01 import models # 必须在项目加载后导入
# all 查询所有的数据 QuerySet 对象列表 [对象,对象]
ret = models.Person.objects.all()
'''
调用:
def __repr__(self):
return '<%s: %s>' % (self.__class__.__name__, self)
也可以重新定义
def __repr__(self):
return "{}-{}".format(self.name, self.age)
'''
print(ret)
'''
打印对象的时候会调用__str__(self)方法,
因为先前已经重新定义了
def __str__(self):
return "{}-{}".format(self.name, self.age)
所以打印格式为xiefei-22
默认:
def __str__(self):
return '%s object (%s)' % (self.__class__.__name__, self.pk)
打印:Person object (3)
'''
# get 获取一个且唯一的数据 对象 没用或者多个数据就报错
ret1 = models.Person.objects.get(name="xiefei")
print(ret1)
# filter 获取满足条件的多条数据 对象列表 [对象 对象] 没用为空
ret2 = models.Person.objects.filter(age=22)
print(ret2)
# 排序 默认升序 降序:字段前加- 可以多个字段排序,
ret3 = models.Person.objects.all().order_by("age", "-pid")
print(ret3)
# reverse 反转 对已经排序的对像列表进行排序
ret4 = models.Person.objects.all().order_by("pid").reverse()
print(ret4)
# values() QuerySet[{字段:值},{...}] 把每一个对象编程字典类型 {字段: 值}
# 可以指定字段
ret5 = models.Person.objects.all().values("pid", "name")
# print(ret5)
print("-------------------------")
for i in ret5:
print(i)
# 只获取字段对应的值 不获取字段名 ()元组类型
ret6 = models.Person.objects.all().values_list("pid", "name")
for i in ret6:
print(i)
# distinct 去重
ret7 = models.Person.objects.values("age").distinct()
print(ret7)
# count 计数
ret8 = models.Person.objects.all().count() # 效率跟高
ret81 = len(models.Person.objects.all())
print(models.Person.objects.filter(age=22).count())
print(ret8, ret81)
# first() 获取第一个元素
ret9 = models.Person.objects.all().first()
print(ret9)
# last() 最后一个
ret10 = models.Person.objects.all().last()
print(ret10)
# exists() 判断数据库是否有这条数据
ret11 = models.Person.objects.filter(pid=3).exists()
print(ret11)
# 排除 exclude()
ret12 = models.Person.objects.exclude(pid=1)
print(ret12)
'''
返回对象列表QuerySet:
all
filter
exclude
order_by
reverce
values[{}.{}]
values_list[(),()]
distinct
返回对象:
get
first
last
返回数字:
count
返回bool:
exists
'''
单表的双下划线
models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值
models.Tb1.objects.filter(id__lte=10, id__gte=1) # 获取id大于党羽1 且 小于等于10的值
models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in
models.Tb1.objects.filter(name__contains="ven") # 获取name字段包含"ven"的
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
models.Tb1.objects.filter(id__range=[1, 3]) # id范围是1到3的,等价于SQL的bettwen and
类似的还有:startswith,istartswith, endswith, iendswith
date字段还可以:
models.Class.objects.filter(first_day__year=2017)
models.Class.objects.filter(first_day__year=2017)
外键 (一对多关系)
from django.db import models
# Create your models here.
class Person(models.Model):
pid = models.AutoField(primary_key=True) # 主键
name = models.CharField(max_length=32) # varchar(32)
age = models.IntegerField() # 整型
# birth = models.DateTimeField(auto_now_add=True) # 每当新增数据时 自动保存当前时间
birth = models.DateTimeField(auto_now=True) # 每当新增和编辑数据时 自动保存当前时间
def __str__(self):
return "{}-{}-{}".format(self.pid, self.name, self.age)
# __repr__ = __str__
def __repr__(self):
return "{}-{}-{}".format(self.pid, self.name, self.age)
class Press(models.Model):
def __str__(self):
return "Press object:{}-{}".format(self.id, self.name)
def __repr__(self):
return "Press object:{}-{}".format(self.id, self.name)
name = models.CharField(max_length=32, verbose_name='出版社名称')
class Book(models.Model):
name = models.CharField(max_length=32, verbose_name='书籍名称')
press = models.ForeignKey(Press, on_delete=models.CASCADE, related_name="books")
# 设置反向查询的名称 默认类 名小写_set
# related_query_name="" 字段查询名称
def __str__(self):
return "Book object:{}-{}".format(self.id, self.name)
def __repr__(self):
return "Press object:{}-{}".format(self.id, self.name)
# !/usr/bin/env python
# -*- coding: UTF-8 -*-
# 作者 :xiefei
# 时间 :2020/8/2 17:17
# IDE :PyCharm
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'orm_base.settings')
django.setup()
if __name__ == '__main__':
from app01 import models
# 基于对象的查询
# 正向查询
book_obj = models.Book.objects.get(id=1)
print(book_obj.id)
print(book_obj.press_id)
# 反向查询
# 未有指定 related_name 默认 类名小写_set
press_obj = models.Press.objects.get(id=1)
print(press_obj.books, type(press_obj.books)) # 默认类名小写_set
print(press_obj.books.all())
# 基于字段的查询
ret3 = models.Book.objects.filter(name="资治通鉴")
print(ret3)
# 通过子表查询父表数据
ret4 = models.Book.objects.filter(press__name="新华出版社")
# ret4 = models.Book.objects.filter(press__name__id="新华出版社")
print(ret4)
# 未有指定 related_name 默认 类名小写__
ret5 = models.Press.objects.filter(books__name='资治通鉴')
print(ret5)
外键多对多
# 多对多操作 和外键的操作一样
author_obj = models.Author.objects.get(id=1)
print(author_obj.book)
print(author_obj.book.all())
book_obj1 = models.Book.objects.get(id=1)
print(book_obj.author_set.all())
# 通过书籍表查询作者
print(models.Book.objects.filter(author__name='xiefei'))
# 通过book表设置作者书籍 set
Django 框架get()和filter()返回值的区别 先上官方文档!
filter(**kwargs)
返回包含与给定查找参数匹配的对象的新查询集。
简单来说,返回一个又对象组成的查询集合
get(**kwargs)
返回与给定查找参数匹配的对象,该对象应采用字段查找中描述的格式。
例子
例如在Model中有一个Order类,包含一个id字段,输入 id 为2019 字段的 id
1.get()方法
orders = Orders.objects.get(id=20190003)
print(order)
1
2
先查看orders是什么,结果为
Orders object
1
按照官方文档所说的,他是一个对象没错,可以直接用点操作进行字段取值
print(order.id)
1
结果就是20190003
2.filter() 方法
orders = Orders.objects.filter(id=20190003)
print(order)
1
2
先查看orders是什么
<QuerySet [<Orders:Orders object>]>
1
我认为 前面的QuerySet 是告诉我们这个是一个查询集,真正的查询集内容是列表[]里面的东西,<>表示查询集的范围。[]中的Orders同理。这个时候我们发现[]中的东西就是get()方法所获得东西,因此只需要取order[0]即可,打印order[0]可以看见
Orders object
1
因此,order[0].id.也就能获得20190003
备注: 如果filter查询返回的结果多条,结果为
<QuerySet [<Orders:Orders object>,<Orders:Orders object>,<Orders:Orders object>]>
1
本质上看起来为一个列表
总结:get()返回的是一个对象,filter()返回的是由对象组成的列表,称为查询集