Django 单表操作

orm介绍

查询数据层次图解:如果操作mysql,ORM是在pymysq之上又进行了一层封装

MVC或者MTV框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动

ORM是“对象-关系-映射”的简称。

单表操作

在创建的名为app01的项目下的models.py文件内创建模型:

from django.db import models

# Create your models here.
class Book(models.Model):
    id=models.AutoField(primary_key=True)
    name=models.CharField(max_length=32)
    price=models.DecimalField(max_digits=6,decimal_places=2)
    publish=models.CharField(max_length=32)
    author=models.CharField(max_length=32)
    create_date=models.DateField(null=True)
    def __str__(self):
        return '书名:%s,作者:%s,出版社:%s,价格:%s,出版时间:%s'%(self.name,self.author,self.publish,self.price,self.create_date)

字段参数

每个字段有一些特有的参数,例如,CharField需要max_length参数来指定VARCHAR数据库字段的大小。还有一些适用于所有字段的通用参数。 这些参数在文档中有详细定义

---字段---
AutoField(Field)
        - int自增列,必须填入参数 primary_key=True

    BigAutoField(AutoField)
        - bigint自增列,必须填入参数 primary_key=True

        注:当model中如果没有自增列,则自动会创建一个列名为id的列
        from django.db import models

        class UserInfo(models.Model):
            # 自动创建一个列名为id的且为自增的整数列
            username = models.CharField(max_length=32)

        class Group(models.Model):
            # 自定义自增列
            nid = models.AutoField(primary_key=True)
            name = models.CharField(max_length=32)

    SmallIntegerField(IntegerField):
        - 小整数 -32768 ~ 32767

    PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正小整数 0 ~ 32767
    IntegerField(Field)
        - 整数列(有符号的) -2147483648 ~ 2147483647

    PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正整数 0 ~ 2147483647

    BigIntegerField(IntegerField):
        - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807

    自定义无符号整数字段

        class UnsignedIntegerField(models.IntegerField):
            def db_type(self, connection):
                return 'integer UNSIGNED'

        PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
            'AutoField': 'integer AUTO_INCREMENT',
            'BigAutoField': 'bigint AUTO_INCREMENT',
            'BinaryField': 'longblob',
            'BooleanField': 'bool',
            'CharField': 'varchar(%(max_length)s)',
            'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
            'DateField': 'date',
            'DateTimeField': 'datetime',
            'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
            'DurationField': 'bigint',
            'FileField': 'varchar(%(max_length)s)',
            'FilePathField': 'varchar(%(max_length)s)',
            'FloatField': 'double precision',
            'IntegerField': 'integer',
            'BigIntegerField': 'bigint',
            'IPAddressField': 'char(15)',
            'GenericIPAddressField': 'char(39)',
            'NullBooleanField': 'bool',
            'OneToOneField': 'integer',
            'PositiveIntegerField': 'integer UNSIGNED',
            'PositiveSmallIntegerField': 'smallint UNSIGNED',
            'SlugField': 'varchar(%(max_length)s)',
            'SmallIntegerField': 'smallint',
            'TextField': 'longtext',
            'TimeField': 'time',
            'UUIDField': 'char(32)',

    BooleanField(Field)
        - 布尔值类型

    NullBooleanField(Field):
        - 可以为空的布尔值

    CharField(Field)
        - 字符类型
        - 必须提供max_length参数, max_length表示字符长度

    TextField(Field)
        - 文本类型

    EmailField(CharField):
        - 字符串类型,Django Admin以及ModelForm中提供验证机制

    IPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制

    GenericIPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
        - 参数:
            protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
            unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"

    URLField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证 URL

    SlugField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)

    CommaSeparatedIntegerField(CharField)
        - 字符串类型,格式必须为逗号分割的数字

    UUIDField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证

    FilePathField(Field)
        - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
        - 参数:
                path,                      文件夹路径
                match=None,                正则匹配
                recursive=False,           递归下面的文件夹
                allow_files=True,          允许文件
                allow_folders=False,       允许文件夹

    FileField(Field)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage

    ImageField(FileField)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
            width_field=None,   上传图片的高度保存的数据库字段名(字符串)
            height_field=None   上传图片的宽度保存的数据库字段名(字符串)

    DateTimeField(DateField)
        - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]

    DateField(DateTimeCheckMixin, Field)
        - 日期格式      YYYY-MM-DD

    TimeField(DateTimeCheckMixin, Field)
        - 时间格式      HH:MM[:ss[.uuuuuu]]

    DurationField(Field)
        - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型

    FloatField(Field)
        - 浮点型

    DecimalField(Field)
        - 10进制小数
        - 参数:
            max_digits,小数总长度
            decimal_places,小数位长度

    BinaryField(Field)
        - 二进制类型
---参数---
(1)null
如果为True,Django 将用NULL 来在数据库中存储空值。 默认值是 False.
 
(1)blank
如果为True,该字段允许不填。默认为False。
要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。
如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。
 
(2)default
字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用。
 
(3)primary_key
如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True,
Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,
否则没必要设置任何一个字段的primary_key=True。
 
(4)unique
如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的
 
(5)choices
由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,<br>而且这个选择框的选项就是choices 中的选项。

配置

models.py模型创建好后 在settings.py需要进行数据库的配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'day76',
        'HOST':'127.0.0.1',
        'PORT':3306,
        'USER':'root',
        'PASSWORD':'admin'
    }
}
#'NAME':要连接的数据库,连接前需要创建好,django不会创建数据库
#'USER':连接数据库的用户名
#'PASSWORD':连接数据库的密码
#'HOST':连接主机,默认本机
#'PORT':端口 默认3306

接下来在项目下的_ _ init _ _.py文件内输入

import pymysql
pymysql.install_as_MySQLdb()

最后通过

python manage.py makemigrations
python manage.py migrate

这两条命令即可在数据库内创建表

表的操作

#插入数据的两种方式
    # 方式一 :返回结果是一个对象
    book=models.Book.objects.create(name='红楼梦',price=23.8,publish='人民出版社',author='曹雪芹',create_data='2018-09-17')
    # 方式二:先实例化产生对象,然后调用save方法,保存
    book=models.Book(name='水浒传',price=99.8,publish='老男孩出版社',author='施耐庵',create_data='2018-08-08')
    book.save()
    print(book.name)
    # 时间格式,可以传字符串,可以传日期格式
    import datetime

    ctime = datetime.datetime.now()
    book = models.Book.objects.create(name='西游记', price=73.8, publish='北京出版社', author='吴承恩', create_data=ctime)
    
#删除
    # 删除名字叫西游记的这本书
    ret=models.Book.objects.filter(name='西游记').delete()
    # 删除的第二种方式:
    ret = models.Book.objects.filter(name='西游记').first()
    ret.delete()
    
#修改
    ret=models.Book.objects.filter(name='西游记').update(price=20.9)
    # 对象修改(没有update方法,但是可以用save来修改)
    book = models.Book.objects.filter(name='西游记').first()
    book.price=89
    book.save()
    
#查询
    (1)all()
    ret=models.Book.objects.all()
    print(ret)
    (2)filter()
    # 查询名字叫西游记的这本书
    ret=models.Book.objects.filter(name='西游记').first()
    # 不支持负数,只支持正数
    ret=models.Book.objects.filter(name='西游记')[-1]
    # filter内可以传多个参数,用逗号分隔,他们之间是and的关系
    ret=models.Book.objects.filter(name='西游记',price='73.8')
    # ret.query -->queryset对象打印sql
    print(ret.query)
    # get() 有且只有一个结果,才能用,如果有一个,返回的是对象,不是queryset对象,通常用在,用id查询的情况
    ret=models.Book.objects.get(name='红楼梦')
    ret=models.Book.objects.get(id=1)
    # exclude()查询名字不叫西游记的书,结果也是queryset对象
    ret=models.Book.objects.exclude(name='西游记',price='23.8')
    #这里是查询 不是书名为西游记并且价格为23.8的书 exclude把括号内的多个条件当成一个整体来进行查询的
    # order_by 按价格升序排
    ret=models.Book.objects.all().order_by('price')
    # queryset对象可以继续 点 方法
    ret=models.Book.objects.all().order_by('price').filter(name='西游记')
    # 按价格倒序排
    ret=models.Book.objects.all().order_by('-price')
    # 可以传多个
    ret=models.Book.objects.all().order_by('-price','create_data')
    # reverse 对结果进行反向排序
    ret=models.Book.objects.all().order_by('-price').reverse()
    # count  查询结果个数
    ret=models.Book.objects.all().count()
    ret=models.Book.objects.all().filter(name='西游记').count()
    # last 返回book对象
    ret=models.Book.objects.all().last()
    # exists 返回结果是布尔类型
    ret=models.Book.objects.filter(name='三国演义').exists()
    # values(*field): queryset对象里套字典
    ret=models.Book.objects.all().values('name','price')
    ret=models.Book.objects.all().values('name')
    # value_list queryset对象里套元组
    ret=models.Book.objects.all().values_list('name','price')
    # distinct() 必须完全一样,才能去重   只要带了id,去重就没有意义了
    ret=models.Book.objects.all().values('name').distinct()

基于双下划綫的模糊查询

	# 查询价格大于89 的书
    ret=models.Book.objects.filter(price__gt='89')
    # 查询价格小于89 的书
    ret=models.Book.objects.filter(price__lt='89')

    ret=models.Book.objects.filter(price__lt='89',price='89')
    # 小于等于
    ret=models.Book.objects.filter(price__lte='89')
    # 大于等于,
    ret = models.Book.objects.filter(price__gte='89')
    
    # in 在XX中
    ret=models.Book.objects.filter(price__in=['23.8','89','100'])

    # range 在XX范围内 between and
    ret=models.Book.objects.filter(price__range=[50,100])

    # contains  查询名字有'%红%'的书
    ret=models.Book.objects.filter(name__contains='红')

    # icontains 查询名字带p的书,忽略大小写
    ret=models.Book.objects.filter(name__icontains='P')

    # startswith  以XX开头
    ret=models.Book.objects.filter(name__startswith='红')

    # endswith	以XX结尾
    ret=models.Book.objects.filter(name__endswith='梦')

    # pub_date__year 按年查询 也有create_data__month  create_data__day
    ret=models.Book.objects.filter(create_data__year='2017')
posted @ 2018-11-12 21:27  大张哥  阅读(143)  评论(0编辑  收藏  举报