zoukankan      html  css  js  c++  java
  • 04-Django模型(1)

    模型

      MTV图解

     ORM

      ORM全拼:Object-Relation-Mapping翻译就是对象关系映射。在MVC/MTV设计模式中的Model模块中都包括ORM。主要实现模型对象到关系数据库数据的映射。比如:把数据库表中每条记录映射为一个模型对象

      ORM图解

     优点:

      只需要面向对象编程,不需要面向数据库编写代码。对数据库的操作都转化为对类属性和方法的操作,不用编写各种数据库的sql语句

      实现了数据模型与数据库的解耦,屏蔽了不同数据库操作上的差异。通过简单地配置就可以轻松更换数据库,而不需要修改代码。

    缺点:

      相比较直接使用SQL语句操作数据库,有性能缺失。会转化为sql语句在执行。多了流程。根据对象的操作转换成sql语句,根据查询的结果转化成对象,在映射过程中有性能损失。

    项目准备

        1、创建项目

    django-admin startproject BookManager

      2、创建应用

    python manage.py startapp Book

      3、安装应用

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'Book',
    ]

      4、本地化

    LANGUAGE_CODE = 'zh-Hans'
    
    TIME_ZONE = 'Asia/Shanghai'

      5、创建模板路径

        在应用同级目录下,创建templates模板文件

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            #模板路径
            'DIRS': [os.path.join(BASE_DIR,"templates")],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]

    6、应用中分发路由

    from django.contrib import admin
    from django.urls import path
    from Book import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('booklist/', views.bookList),
    ]

    7、准备视图函数

    from django.shortcuts import render
    from django.http import HttpResponse
    # Create your views here.
    
    
    #书籍列表信息视图
    def bookList(request):
        return HttpResponse("ok")

    8、开启服务器,测试项目

    python manage.py runserver

    http://127.0.0.1:8000/

    MYSQL数据库

      Django项目默认采用sqlite3数据库,但是Web项目首选的数据库是mysql数据库,所以我们需要修改Django项目默认的数据库为mysql数据库

    安装pymysql包

      pymysql包用于跟mysql数据库交互,没有pymysql包会报错:Error loading MySQLdb module: No module named MySQLdb

    pip3 install pymysql

    pymysql包配置:

    配置项目mysql数据库(settings.py)

      默认配置:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }

      配置mysql数据库:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',  # 数据库引擎
            'NAME': 'Bookdb',  # 数据库名称
            'HOST': 'localhost',  # 数据库主机(建议使用主机真实IP)
            'PORT': '3306',  # 数据库端口
            'USER': 'root',  # 数据库用户名
            'PASSWORD': '',  # 数据库密码
        }
    }

    创建项目mysql数据库

      打开cmd终端,打开数据库,链接数据库。创建数据库名字:

    create database bookdb charset=utf8;
      use Bookdb;
    show tables;
    #退出数据库
    exit

    字段类型

      当为项目创建好mysql类型的数据库bookdb后,需要创建模型类并生成和执行迁移表,从而创建数据库表。但是在创建模型类需要指定模型属性和属性类型。

      模型属性和属性类型,也就是对应数据库中的字段和字段类型

    模型类定义属性:

      语法:属性名 = models.字段类型(选项)

    # 书籍信息模型
    class Book(models.Model):
        name = models.CharField(max_length=20) #图书名称

    备注:属性名1、不允许使用python的保留关键字,2、不允许使用mysql的保留关键字,3、不允许使用连续的下划线,因为Django的查询语法就是连续的下划线。

    字段类型

    AutoField:自动增长的IntegerField,通常不用指定,不指定时Django会自动创建属性名为id的自动增长属性
    
    BooleanField:布尔字段,值为True或False
    NullBooleanField:支持Null、True、False三种值
    CharField(max_length
    =字符长度):字符串参数max_length表示最大字符个数
    TextField:大文本字段,一般超过4000个字符时使用
    IntegerField:整数
    DecimalField(max_digits
    =None, decimal_places=None):可以指定精度的十进制浮点数 参数max_digits表示总位数 参数decimal_places表示小数位数
    FloatField:浮点数
    DateField[auto_now
    =False, auto_now_add=False]):日期,参数auto_now表示每次保存对象时,自动设置该字段为当前时间,用于"最后一次修改"的时间戳,
    它总是使用当前日期,默认为false 参数auto_now_add表示当对象第一次被创建时自动设置当前时间,用于创建的时间戳,它总是使用当前日期,默认为false 参数auto_now_add和auto_now是相互排斥的,组合将会发生错误
    TimeField:时间,参数同DateField
    DateTimeField:日期时间,参数同DateField
    FileField:上传文件字段
    ImageField:继承于FileField,对上传的内容进行校验,确保是有效的图片

    选项

    通过选项实现对字段的约束
    null:如果为True,表示允许为空,默认值是False
    blank:如果为True,则该字段允许为空白,默认值是False
    对比:null是数据库范畴的概念,blank是表单验证范畴的
    db_column:字段的名称,如果未指定,则使用属性的名称
    db_index:若值为True, 则在表中会为此字段创建索引,默认值是False
    default:默认值
    primary_key:若为True,则该字段会成为模型的主键字段,默认值是False,一般作为AutoField的选项使用
    unique:如果为True, 这个字段在表中必须有唯一值,默认值是False
    注意:Django会自动为表创建主键字段 如果使用选项设置某属性为主键字段后,Django不会再创建自动增长的主键字段 默认创建的主键字段为id,可以使用pk代替,pk全拼为primary key

    关系字段类型

    关系型数据库的关系包括三种类型:
      ForeignKey:一对多,将字段定义在多的一端中   

      ManyToManyField:多对多,将字段定义在任意一端中
      

    OneToOneField:一对一,将字段定义在任意一端中
    可以维护递归的关联关系,使用self指定,详见“自关联”

    元模型类

      作用:在模型类中定义 元类Meta,用于设置元信息,用db_table 自定义表的名字

     # 书籍信息模型
      class BookInfo(models.Model):
          name = models.CharField(max_length=20) #图书名称
    
          class Meta: #元信息类
              db_table = 'bookinfo' #自定义表的名字

    #在数据库中更改表名

    查看表结构(数据库的客户端查看)

    desc 表明 

    定义模型

      定义的模型可以是这个样子

    #书籍信息
    ("与时间做朋友","2002-08-22","45.21","中信出版社","athor_id")
    
    #人物信息
    ("李笑来","","年龄","家庭地址","电话")

    因此模型代码如下:

    from django.db import models
    
    # Create your models here.
    #创建作者信息表
    class Authors(models.Model):
        name = models.CharField(max_length=20)#作者名字
        gender = models.BooleanField(default=True)#性别
        age = models.IntegerField()#年龄
        addr = models.CharField(max_length=60)
        tel = models.IntegerField()
        #元类修改表名
        class Meta:
            db_table = "authors"
    
    #创建书籍信息
    class Books(models.Model):
        name = models.CharField(max_length=20)#书名
        pub_data = models.DateField(null=True)#出版日期
        #参数max_digits表示总位数 参数decimal_places表示小数位数
        price = models.DecimalField(max_digits=8,decimal_places=2)#价格
        publish = models.CharField(max_length=20)
        #外键 将字段定义在多的一端中 级联删除
        author = models.ForeignKey(Authors,on_delete=models.CASCADE)
        #修改表名(元类)
        class Meta:
            db_table = "books"

    模型迁移不要忘记:

    python manage.py makemigrations
    
    python manage.py migrate

    查看表结构:

    去站点插点数据(如果嫌慢就用sql语句插数据)(需要设置站点,1、注册管理模型类,需要显示完整的,重写类,list_display重新注册,启动超级用户,python manage.py createsuperuser)

     

     展示模型数据

      网址:http://127.0.0.1:8000/booklist

      路由部分:

    from django.contrib import admin
    from django.urls import path
    from Book import views
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('booklist/', views.bookList),
    ]

      视图部分:

    from django.shortcuts import render
    from django.http import HttpResponse
    # Create your views here.
    from Book.models import *
    
    #书籍列表信息视图
    def bookList(request):
        #查询数据库书籍信息
        booklist = Books.objects.all()
        #构造上下文
        content = {"booklist":booklist}
        #传入模板 返回由视图发送给浏览器
        return render(request,"Book/booklist.html",content)

      模板部分:

    from django.db import models
    
    # Create your models here.
    #创建作者信息表
    class Authors(models.Model):
        name = models.CharField(max_length=20)#作者名字
        gender = models.BooleanField(default=True)#性别
        age = models.IntegerField()#年龄
        addr = models.CharField(max_length=60)
        tel = models.IntegerField()
        #元类修改表名
        class Meta:
            db_table = "authors"
        def __str__(self):
            return self.name
    #创建书籍信息
    class Books(models.Model):
        name = models.CharField(max_length=20)#书名
        pub_data = models.DateField(null=True)#出版日期
        #参数max_digits表示总位数 参数decimal_places表示小数位数
        price = models.DecimalField(max_digits=8,decimal_places=2)#价格
        publish = models.CharField(max_length=20)
        #外键 将字段定义在多的一端中 级联删除
        author = models.ForeignKey(Authors,on_delete=models.CASCADE)
        #修改表名(元类)
        class Meta:
            db_table = "books"
    
        def __str__(self):
            return self.name

       结果:

     模型中重要的实例方法和属性

      模型实例方法

    str : 在将对象转换成字符串时会被调用
    
    save : 将模型对象保存到数据库表中
    
    delete : 将模型对象从数据库表中删除

      objects模型属性

    objects : 管理器对象是Manager类型的对象,定义在from django.db import models中用于模型对象和数据库交互
    是默认自动生成的属性,但是可以自定义管理器对象自定义管理器对象后,Django不再生成默认管理器对象objects

    自定义管理器对象,原本默认的是objects = models.Manager(),可以自定义,重新实例化管理器对象。

    查询操作

    • 查询集:表示从数据库中获取的模型对象集合
      • 在管理器上调用过滤器方法会返回查询集
      • 查询集可以含有0个、一个或多个过滤器
    • 过滤器:基于所给的参数限制查询的结果
    • 提示:从sql的角度,查询集和select语句等价,过滤器像where和limit语句

    返回列表的过滤器如下: 

    all():返回所有的数据
    filter():返回满足条件的数据
    exclude():返回满足条件之外的数据,相当于sql语句中where部分的not关键字
    order_by():返回排序后的数据

    返回单个对象的过滤器如下:

    get():返回单个满足条件的对象
    如果未找到会引发"模型类.DoesNotExist"异常
    如果多条被返回,会引发"模型类.MultipleObjectsReturned"异常
    count():返回当前查询的总条数
    aggregate():聚合
    exists():判断查询集中是否有数据,如果有则返回True,没有则返回False

    查询集的特点

      1、惰性执行:创建查询集不会访问数据库,直到在模板中调用数据时,才会访问数据库。

    调用数据的情况包括迭代、序列化、与if合用

      2、缓存:查询集的结果被存下来之后,再次查询相同数据时会使用之前缓存的数据

     每个查询集都包含一个缓存来最小化对数据库的访问,第一次查询数据后,Django会将查询集缓存起来,并返回请求的结果,再次查询相同数据时将重用缓存的结果。

    限制查询集

    • 查询集返回列表,可以使用下标的方式进行限制,等同于sql中的limitoffset语句
    • 注意:不支持负数索引
    • 使用下标后返回一个新的查询集,不会立即执行查询
    • 如果获取一个对象,直接使用[0],等同于[0:1].get()

      • 但是如果没有数据,[0]引发IndexError异常,[0:1].get()引发DoesNotExist异常

    基础条件查询

      查询语法

    filter(模型属性__条件运算符=值)
    例:
    filter(name__contains='')

      说明:查询语句是属性名称和比较运算符间使用两个下划线相连,所以定义的模型属性名不能包括多个下划线

      实现sql中where的功能,可以调用过滤器filter()、exclude()、get()

      查询需求

    # 1.查询id为1的书籍
    # 2.查询书名包含‘时间’的书籍
    # 3.查询书名以‘观’结尾的书籍
    # 4.查询书名不为空的书籍
    # 5.查询价格为50或52的书籍
    # 6.查询价格大于52的书籍
    # 7.查询id不等于3的书籍
    # 8.查询2019年发表的书籍
    # 9.查询2000年1月1日后发表的书籍

      查询实现

    1.查询id为1的书籍(exact:判断相等)
     #1、查询id为1的书籍(exact: 判断相等)<QuerySet [<Books: 与时间做朋友>]>
       book = Books.objects.all()
    book1 = book.filter(id__exact=1)
    2.查询书名包含‘时间’的书籍(contains:是否包含)
        book = Books.objects.all()
        book1 = book.filter(name__contains="局观")

    #<QuerySet [<Books: 大局观>]>

    
    
    3.查询书名以‘与’开始的书籍(startswith,endswith)
     book = Books.objects.all()
        book1 = book.filter(name__startswith="")
        print(book1)
     4.查询书名不为空的书籍(isnull:是否为null)
     book = Books.objects.all()
        book1 = book.filter(name__isnull=False)
        print(book1)
    5.查询价格为50或52的书籍(in:是否包含在这范围内)
     book = Books.objects.all()
        book1 = book.filter(price__in=[50,52])
        print(book1)
    6.查询价格大于52的书籍(gt,gte,it,ite:大于,大于等于,小于,小于等于)
        book = Books.objects.all()
        book1 = book.filter(price__gt=52)
        print(book1)
    
    
     7.查询id不等于3的书籍(exclude:条件以外的数据)
       book = Books.objects.all()
        book1 = book.exclude(id=3)
        print(book1)
     8.查询2019年发表的书籍(yearmonthdayweek_dayhourminutesecond:对日期时间类型的属性进行运算)
        book = Books.objects.all()
        book1 = book.filter(pub_data__year=2019)
        print(book1)
     9.查询2000年1月1日后发表的书籍
       from datetime import date
        book = Books.objects.all()
        book1 = book.filter(pub_data__gt=date(2000,1,1))
        print(book1)

    备注:

    • exactcontainsstartswithendswith运算符都区分大小写
    • 在这些运算符前加上i表示不区分大小写
      • iexacticontainsistartswithiendswith
    其他特殊查询下一节分享总结(F和Q查询,聚合函数,关联查询)
  • 相关阅读:
    [转载]PhotoShop性能优化
    SVN常用命令
    [转载]SVN使用教程
    MyEclipse Java Build Path详解
    MyEclipse安装后需要进行的配置
    c#中base64加密解密
    C# MD5 加密
    C# http Post 方法
    EPF与Myeclipse 增强代码自动智能提示
    汉字代码手册
  • 原文地址:https://www.cnblogs.com/lishuntao/p/11654406.html
Copyright © 2011-2022 走看看