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类型字段python
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操做须要配置的参数sql
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):一对多字段建在多的那一方django
多对多(ManyToManyField):多对多字段不管建在哪张表里面均可以,可是推荐建在查询频率比较高的那张表里面app
# 直接写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表,直接.属性拿到值
反向:查询按对应表名小写code
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的做者,一对一关系
正向orm
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终端上