Django之模型层

Django之模型层

关键性字段及参数

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')
集合查询 aggregate
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'))
分组查询(group by) annotate
# 统计每个出版社出版的书的平均价格
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内部到底是怎么执行它的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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值