Django中数据库及后台管理

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/Feng_xiaowu/article/details/102731297

数据库操作

配置

  1. 安装驱动程序------pip install pymysql

  2. 在同名子目录的__init__.py文件中添加下列语句

    from pymysql import install_as_MySQLdb
    
    install_as_MySQLdb()
    

    其作用是让Django的ORM能以mysqldb的方式调用PyMySQL

  3. 修改配置文件

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': 'localhost',  # 数据库主机
            'PORT': 3306,  # 数据库端口
            'USER': 'root',  # 数据库用户名
            'PASSWORD': '******',  # 数据库用户密码
            'NAME': 'two_demo'  # 数据库名字
        }
    }
    
  4. 在mysql中创建同名数据库

    create database two_demo default charset=utf8;
    

模型定义

  • 数据库表名-------默认为**子应用名称小写_模型类名小写**;可以通过db_table来自主指明数据库名称

  • 主键: django会为表创建自动增长的主键列,每个模型只能有一个主键列,若自主设置主键,则不会再创建自动增长的主键列,默认主键的属性为id,可以使用pk来替代

  • 字段属性

    类型 说明
    AutoField 自动增长的IntegerField,通常不用指定,会自动创建自增长的属性
    BooleanField 布尔类型,True和False
    NullBooleanField 支持Null、True、False三种数据类型
    CharField 字符串,参数max_length表示最大字符个数
    TextField 大文本字段,一般超过4000个字符时使用
    IntegerField 整数
    DecimalField 十进制浮点数,参数max_digits表示总位数,参数decimal_places表示小数位,通常用于存储金额
    FloatField 浮点数
    DateField 日期,有两个参数auto_now_add和auto_now_add;其中auto_now_add默认值为false,设为true时,能在保存该字段时,将其值设置为当前时间,并且每次改动,都会自动更新;而auto_now_add默认值也为false,设置为true时,会在model对第一次被创建时,将其字段的值设为创建时间,以后修改对象时,字段的值不会再更新.注意两个不能组合使用,会相互排斥
    TimeField 时间,参数同DateField
    DateTimeField 日期时间,参数同DateField
    FileField 上传文件字段
    ImageField 继承于FileField,对上传的内容进行校验,确保是有效的图片
  • 外键

    设置外键时,需要通过**on_delete**选项指明主表删除数据是,对于外键引用表数据如何处理,有以下可选常量:

    • CASCADE--------级联,删除主表数据时联通一起删除从表中的数据
    • PROTECT----------保护,通过抛出ProtectedError异常,来阻止删除主表中被外键应用的数据
    • SET_NULL-------设置为NULL,仅在该字段null=True允许为null是可用
    • SET_DEFAULT------设置为默认值,仅在该字段设置了默认值时可用
    • SET()--------设置为特定值或者调用特定方法

迁移

  • 生成迁移文件

    python manage.py makemigrations
    
  • 同步到数据库中

    python manage.py migrate
    

数据库----增加

  • save()

    def create_book(request):
        # 第一种创建方式
        book = BookInfo()
        book.bname = "西游记"
        book.bdate = "1980-01-01"
        book.bcomment = 500
        book.breaded = 10000
        book.save()
    
  • create()

    BookInfo.objects.create(
            bname="东游记",
            bdate="1980-05-03",
            bcomment=500,
            breaded=5000
        )
    

数据库----删除

  • 模型类对象.delete()

    def delete_hero(request):
        # 第一种删除方式
        # hero = HeroInfo.objects.filter(hname="孙悟空").first()
        # hero.delete()
    
    
  • 模型类.objects.filter().delete()

    # 第二种
        HeroInfo.objects.filter(hname="袁紫衣").delete()
    

数据库----修改

  • save

    def update_hero(request):
        # 第一种
        # hero = HeroInfo.objects.filter(hname="孙悟空").first()
        # hero.hname = "孙大圣"
        # hero.save()
    
    
  • objects.filter().update()

    # 第二种
        HeroInfo.objects.filter(hname="孙大圣").update(hname="孙悟空")
    

数据库----查询

基本查询

  • get 查询单一结果,若不存在会抛出模型类.DoseNotExist异常
  • all查询多个结果
  • count查询结果数量
# 查询编号为1的图书[二种方式]
    # 使用filter查询的结果为一个查询集
    book = BookInfo.objects.filter(id=1)
    book = BookInfo.objects.get(id=1)

    # pk代表主键
    book = BookInfo.objects.get(pk=1)
    print(book)

    # 查询所有图书
    # 返回结果类型为查询集
    allbook = BookInfo.objects.all()
    print(allbook)

    # 查询所有图书的数量
    number = BookInfo.objects.count()
    print(number)
    
    # 若不存在,报错
    BookInfo.objects.get(id=100)
    Traceback (most recent call last):
        db.models.DoesNotExist: BookInfo matching query does not exist.

过滤查询

  • filter过滤出多个结果

  • exclude排除掉符合条件剩下的结果(取反)

  • get过滤单一结果

  • 表达式格式为**属性名称__比较远算符=值**

    • exact----表示相等

      BookInfo.objects.filter(id__exact=1)
      可简写为:
      BookInfo.objects.filter(id=1)
      
    • contain包含

      # 查询书名包含雪山的图书[开头, 结尾]
       book = BookInfo.objects.get(bname__startswith="雪山")
      
      # 若查找不到,则会报错
      book = BookInfo.objects.get(bname__endswith="雪山")
      
      # 查询书名中包含雪山的书籍
      book = BookInfo.objects.filter(bname__contains="雪山")
      print(book)
      
      
    • 空查询-------isnull

       # 查询书籍名不为空的图书
          # book = BookInfo.objects.filter(bname__isnull=False)
          # print(book)
      
    • 范围查询-------in:是否包含在指定范围内

      # 查询书籍编号为1, 3, 5的图书
      book = BookInfo.objects.filter(id__in=[1, 3, 5])
      print(book)
      
    • 比较查询

      • gt—大于

      • gte—大于等于

      • lt—小于

      • lte—小于等于

      • 不等于的运算符,可以使用exclude()

        # 查询编号大于3的图书
        book = BookInfo.objects.filter(id__gt=3)
        print(book)
            
            
        # 查询编号大于等于3的图书
        #book = BookInfo.objects.filter(id__gte=3)
         print(book)
        
           
        # 查询编号不等于3的图书
         book = BookInfo.objects.exclude(id=3)
         print(book)
        
    • 日期查询

      • year、month、day、week_day、hour、minute、second

        # 查询1980年发表的图书
         book = BookInfo.objects.filter(bdate__year=1980)
         # 完整写法
         book = BookInfo.objects.filter(bdate__year__exact=1980)
         print(book)
        
            
        #查询1980年1月1号之后发表的图书
        # 使用date把时间转为一个字符串格式
        book = BookInfo.objects.filter(bdate__gt=date(1980, 1, 1))
        print(book)
        
        

F对象和Q对象

F对象------可以实现两个属性之间进行比较

# 当要进行属性比较的时候使用F
# 查询阅读量大于等于评论量的图书
book = BookInfo.objects.filter(breaded__gte=F('bcomment'))
print(book)

# 查询阅读量大于2倍评论量的图书
# 使用F运算可以在其基础上进行算术运算
book = BookInfo.objects.filter(breaded__gt=F('bcomment')*2)
print(book)
    
    
# 2.1 更新id=1的图书,让他的阅读量自加1
# 第一种,先查到id=1的图书,然后再加一操作
book = BookInfo.objects.get(id=1)
book.bcomment += 1
book.save()

# 第二种,查询到的同时进行加操作
book = BookInfo.objects.filter(id=1).update(bcomment=F('bcomment')+1)
print(book)

Q对象

  • 格式---------Q(属性名__运算符)=值
# 若要进行逻辑或操作,只能通过Q对象来实现
# 查询阅读量大于20,或编号小于3的图书,只能使用Q对象实现
book = BookInfo.objects.filter(Q(breaded__gt=20) | Q(id__lt=3))
print(book)

    
# 查询编号不等于3的图书, 使用Q对象实现
# 通过在Q对象前面加上"~",可以进行取反操作,作用同exclude
 book = BookInfo.objects.filter(~Q(id=3))
 print(book)

聚合函数

  • 使用**aggregate()**过滤器来调用聚合函数,聚合函数包括:Avg、Count、Max、Min、Sum

    # - == = 聚合查询 == ==
    # 查询所有阅读量的总和
    # 通过aggregate来使用聚合函数(Sum,Avg,Count,Max,Min),返回值为一个字典类型
     number = BookInfo.objects.aggregate(Sum('breaded'))
     print(number)
    
    # 查询最大的评论量
    number = BookInfo.objects.aggregate(Max('bcomment'))
    print(number)
    
    # 查询所有图书, 按照阅读量排序, 升序[降序]
    # 升序
    book = BookInfo.objects.all().order_by('breaded')
    
    # 在要进行排序的字段前面加上"-",表示按该字段进行降序排序
    book = BookInfo.objects.all().order_by('-breaded')
    print(book)
    

关联查询及关联过滤查询

# - == == 关联 == ==
# 查询书籍编号为1, 中的所有的英雄
# 若在外键中没有设立relate_name属性,则需使用主表.从表类名_set.all()的方法从主表中获取从表的所有数据
book = BookInfo.objects.get(id=1)
hero = book.heroinfo_set.all()

# 若外键中设置了relate_name属性,则可以使用主表.属性.all()来从主表中获取从表里面的所有数据
book = BookInfo.objects.get(id=1)
hero = book.hero.all()
print(hero)

# - 2.
# 查询书籍名称为雪山飞狐的, 所有的英雄
book = BookInfo.objects.get(bname="雪山飞狐")
hero = book.hero.all()
# hero = book.heroinfo_set.all()
print(hero)

# - 3.
# 查询英雄编号为1, 所属的图书
# 通过从表查主表中的数据,使用从表.外键名来获取
hero = HeroInfo.objects.get(id=1)
book = hero.hbook
print(book)

# - == = 关联过滤查询 == ==
# 查询英雄中有乔峰, 的书籍
# 要查询什么则使用什么模型类名
book = BookInfo.objects.filter(hero__hname="乔峰")
print(book)

# - 2.
# 查询英雄中包含 郭 的书籍
book = BookInfo.objects.filter(hero__hname__contains="郭")
print(book)

# - 3.
# 查询书籍阅读量大于30, 的书中所有英雄
hero = HeroInfo.objects.filter(hbook__breaded__gt=30)
print(hero)

# 4 查询英雄表的前5条数据
data = HeroInfo.objects.all()[:5]
print(data)

Query Set

概念

  • 概念:查询集,也称查询结果集,表示从数据库中获取的对象集合
  • 当调用all()、filter()、exclude()、order_by()

两大特性

  • 惰性执行

    创建查询集不会访问数据库,直到调用数据时,才会访问数据库

  • 缓存

    使用同一个查询集,第一次使用的时候会发生数据库的查询,然后Django会把结果缓存下来,再次使用这个查询集时会使用缓存的数据,减少了数据库的查询次数

管理器

自定义管理器

注意:一但为模型类指明自定义的过滤器后,Django不再生成默认管理对象objects

# 自定义管理器,继承自models.Manager
class BookInfoManager(models.Manager):
    # 重写all()方法
    def all(self):
        # 返回逻辑删除为False的结果(或者说没有进行逻辑删除的结果)
        return super().filter(is_delete=False)

    # 添加新的方法,此处更改了创建数据的方法
    def create_book(self, bname, bdate):
        book = self.model()
        book.bname = bname
        book.bdate = bdate
        book.breaded = 0
        book.bcomment = 0
        book.is_delete = False
        book.save()
        return book
	
    # 在模型类中定义管理器
    class BookInfo(models.Model):
    	...
    	books = BookInfoManager()
    
    
    # ==  采用自定义管理器查询 == #
    # 用自定义的管理器类查询图书的所有数据
    book = BookInfo.books.all()
    print(book)

    # 自定义的books管理器可以用到objects管理器的所有方法
    book = BookInfo.books.create_book("武动乾坤", date(2015, 5, 1))
    print(book)

Admin 站点

  • 创建超级管理员

    python manage.py createsuperuser
    
  • 修改管理员密码使用命令

    python manage.py changepassword 用户名
    
  • 注册模型类

    admin.site.register(模型类名)
    
  • 调整站点信息

    • admin.site.site_header(设置网站页头)
    • admin.site.site_title(设置页面标题)
    • admin.site.index_title(设置首页标语)

猜你喜欢

转载自blog.csdn.net/Feng_xiaowu/article/details/102731297