AutoField:
int自增列,必须填入参数primary_key=True,当model中如果没有自增列,则会自动创建一个名为id的列
IntegerField:
一个整数类型,范围在-2147483648 to 2147483647(一般不用来存手机号,位数也不够,直接用字符串存)
CharField:
字符类型,必须提供max_length参数,max_length表示字符长度
注意:django中的CharField对应Mysql数据库中的varchar类型,没有设置对应char类型的字段,但是可以自定义新的字段
DateField:
日期字段,日期格式:年月日,相当于python中的datetime.date()
DateTimeField:
日期时间字段,格式:年月日 时分秒,相当于python中的datetime.datetime()
上述两个日期字段有两个配置参数:
配置auto_now_add=True:创建数据的时候会把当前时间添加到数据库
配置auto_now=True:每次更新数据记录的时候会更新该字段
自定义char类型字段
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)
单独的py文件测试ORM操作需要配置的参数
import os
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day58.settings") #上面几句从manage.py中复制过来
import django
django.setup()
from app01 import models #这句话必须在这下面导入
#第一种:有返回值,并且就是当前被创建的数据对象
modles.Book.objects.create(name='',price='',publish='',author='',create_time='2019-5-1')
#第二种:先实例化产生对象,然后调用save方法保存
book_obj = models.Book(name='',price='',publish='',author='',create_time='2019-5-1')
book_obj.save()
#queryset方法
res = models.Book.objects.filter(name='').delete()
#对象放法
res = models.Book.objects.filter(name='').first()
res.delete()
#queryset修改
models.Book.objects.filter(name='').update(price='')
#对象修改
book = models.Book.objects.filter(name='').first()
book.price = 66.66
book.save() #对象只有保存方法,这样也能实现修改需求
1.all():查询所有结果
2.filter(**kwargs):它包含了与所给筛选条件相匹配的对象
res = models.User.objects.filter(name='jason',age=17)
filter内可以放多个限制条件但是需要注意的是多个条件之间是and关系
3.get(**kwargs):返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会报错,不推荐
4.exclude(**kwargs):它包含了与所给筛选条件不匹配的对象
res = models.User.objects.exclude(name='lucas')
5.order_by('字段名'):对查询结果排序(升序),如果字段名前加-,则反序排
res = models.User.objects.order_by('age') # 默认是升序
res = models.User.objects.order_by('-age') # 可以在排序的字段前面加一个减号就是降序
6.reverse():对查询结果反向排序,注意要先有排序才能反向
res = models.User.objects.order_by('age').reverse()
7.count():返回数据库中匹配查询(queryset)的对象数量
res = models.User.objects.count()
res = models.User.objects.all().count()
res = models.User.object.filter(pk=1).count()
8.first():返回第一条记录
res = models.User.objects.all().first()
res = models.User.objects.all()[0] #不支持负数
9.last():返回最后一条记录
res = models.User.objects.all().last()
10.exists():如果queryset包含数据,就返回True,否则返回False
res = models.User.objects.all().exists()
res1 = models.User.objects.filter(name='jason',age=3).exists()
11.values('字段名',):返回一个特殊的queryset,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
res = models.User.objects.values('name') #列表套字典
res = models.User.objects.values('name','age')
12.values_list('字段名'):与values()非常相似,返回的是一个元组序列,values返回的是一个字典序列
res = models.User.objects.values_list('name','age') #列表套元组
13.distinct():从返回结果中剔除重复记录
res = models.User.objects.values('name','age').distinct()
# 价格大于
filter(price__gt='90')
# 价格小于
filter(price__lt='90')
# 价格大于等于
filter(price__gte='90')
# 价格小于等于
filter(price__lte='90')
# 存在与某几个条件中
filter(price__in=['11','22','33'])
# 在某个范围
filter(price__range=[50,90]) #顾头顾尾
# 模糊查询
filter(title__contains='n') # 区分大小写
filter(title__icontains='P') # 忽略大小写
# 以什么开头
filter(name__startswith='y')
# 以什么结尾
filter(name__endswith='m')
# 按年查询
filter(ctime__year='2019')
返回queryset对象的方法:all()、filter()、exclude()、order_by()、reverse()、distinct()
values():返回一个可迭代的字典序列
values_list():返回一个可迭代的元组序列
一对一(OneToOneField):一对一字段无论建在哪张表里面都可以,但是推荐建在查询频率比较高的那张表里面
一对多(ForeignKey):一对多字段建在多的那一方
多对多(ManyToManyField):多对多字段无论建在哪张表里面都可以,但是推荐建在查询频率比较高的那张表里面
# 直接写id
models.Book.objects.create(title='红楼梦',price=66.66,publish_id=1)
# 传数据对象
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.create(title='三国演义',price=199.99,publish=publish_obj)
# queryset修改
models.Book.objects.filter(pk=1).update(publish_id=3)
# 传对象
publish_obj = models.Publish.objects.filter(pk=2).first()
models.Book.objects.filter(pk=1).update(publish=publish_obj)
# 对象修改
book_obj = models.Book.objects.filter(pk=1).first()
book_obj.publish_id = 3 # 点表中真实存在的字段名
book_obj.save()
publish_obj = models.Publish.objects.filter(pk=2).first()
book_obj.publish = publish_obj # 点orm中字段名,传该字段对应的表的数据
book_obj.save()
# queryset删除
models.Book.objects.filter(pk=1).delete()
# 对象删除
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.delete()
# add:支持传数字或对象,并且都可以传多个
# 直接写id
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.author.add(1) # 给id为3的书绑定作者id为1的作者
book_obj.author.add(2,3) # 给id为3的书绑定作者id为2和3的作者
# 传对象
author_obj = models.Author.objects.filter(pk=1).first()
book_obj.author.add(author_obj)
# set:传的必须是可迭代对象
book_obj = models.Book.objects.filter(pk=3).first()
# 可以传数字或对象,并且支持传多个
book_obj.author.set((1,)) # 将之前的绑定关系清掉,重新与作者id为1的绑定
book_obj.author.set((1,2,3))
# 传对象
author_list = models.Author.objects.all()
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.author.set(author_list)
# remove:可以传数字或对象,并且支持多个
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.author.remove(1) # 删除id为3的书与id为1的作者的绑定关系
book_obj.author.remove(2,3)
# 传单个对象
author_obj = models.Author.objects.all().first()
book_obj.author.remove(author_obj)
# 传多个对象
author_list = models.Author.objects.all()
book_obj.author.remove(*author_list) # 需要将queryset打散
# clear:清空的是你当前这个表记录对应的绑定关系
book_obj = models.Book.objects.filter(pk=3).first()
book_obj.author.clear() # 清空id为3的书与作者的绑定关系
正向:查询按字段
book_obj = models.Book.objects.filter(title='三国演义').first()
print(book_obj.publish.email) # 查询三国演义对应出版社的邮箱,多对一的关系,.字段名就能直接跳转到对应的publish表,并且就是一个对象,直接.属性就能拿到值
book_obj = models.Book.objects.filter(title='西游记').first()
print(book_obj.author.all()) # 查询西游记对应的作者,多对多关系,.字段名跳转到author表,但是不能直接通过.属性拿到值
user_obj = models.Author.objects.filter(name='lucas').first()
print(user_obj.authordetail.phone) # 查询名为lucas的电话号码,一对一关系,.字段名跳转到对应的authordetail表,直接.属性拿到值
反向:查询按对应表名小写
publish_obj = models.Publish.objects.filter(name='东方出版社').first()
print(publish_obj.book_set.all()) # 查询东方出版社出版的书,一对多关系,
author_obj = models.Author.objects.filter(name='lucas').first()
print(author_obj.book_set.all()) # 查询lucas写过的所有书,多对多关系
authordetail_obj = models.AuthorDetail.objects.filter(phone=111).first()
print(authordetail_obj.author.name) # 查询电话号码为111的作者,一对一关系
正向
res = models.Book.objects.filter(title='三国演义').values('publish__addr','title')
print(res) # 查询书籍为三国演义的出版社地址,字段名__属性就能直接拿到值
res = models.Book.objects.filter(title='西游记').values("authors__name",'title')
print(res) # 查询书籍为西游记的作者的姓名
res = models.Author.objects.filter(name='lucas').values('authordetail__addr')
print(res) # 查询作者lucas的家乡
反向
res = models.Publish.objects.filter(name='南方出版社').values('book__title')
print(res) # 查询南方出版社出版的书
res = models.AuthorDetail.objects.filter(phone=120).values('author__name')
print(res) # 查询电话号码为120的作者姓名
res = models.Author.objects.filter(name='lucas').values('book__title')
print(res) # 查询作者为lucas的写的书的名字
res = models.Book.objects.filter(title='三国演义').values('authors__authordetail__phone')
print(res) # 查询书籍为三国演义的作者的电话号码
# 查询lucas作者的手机号
# 正向
res = models.Author.objects.filter(name='lucas').values('authordetail__phone')
print(res)
# 反向
res = models.AuthorDetail.objects.filter(author__name='lucas').values('phone')
# 查询出版社为东方出版社的所有图书的名字和价格
# 正向
res = models.Publish.objects.filter(name='东方出版社').values('book__title','book__price')
# 反向
res = models.Book.objects.filter(publish__name='东方出版社').values('title','price')
# 查询东方出版社出版的价格大于400的书
# 正向
res = models.Publish.objects.filter(name='东方出版社',book__price__gt=400).values('book__title')
# 反向
res = models.Book.objects.filter(price__gt=400,publish__name='东方出版社').values('title')
from django.db.models import Max,Min,Count,Sum,Aug
# 查询书籍id为3的作者个数
res = models.Book.objects.filter(pk=3).aggregate(count_num=Count('author')) # k,v键值对
# 查询所有出版社出版的平均价格
res = models.Publish.objects.aggregate(avg_price=Avg('book__price'))
# 统计东方出版社出版的书籍的个数
res = models.Publish.objects.filter(name='东方出版社').aggregate(count_num=Count('book__id'))
# 统计每个出版社出版的书的平均价格
res = models.Publish.objects.annotate(avg_price=Avg('book__price')).values('name','avg_price')
# 统计每一本书的作者的个数
res = models.Book.objects.annotate(count_num=Count('author')).values('title','count_num')
# 统计出每个出版社卖的最便宜的书的价格
res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name','min_price')
# 查询每个作者出的书的总价格
res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name','sum_price')
如果你想知道你对数据库进行操作时,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',
},
}
}
配置好之后,再执行任何对数据库进行操作的语句时,会自动将Django执行的sql语句打印到pycharm终端上
原文:https://www.cnblogs.com/yanminggang/p/11012765.html