Python学习----第七模块笔记(Web开发进阶之Django数据库操作)

Posted 青蛙二世

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python学习----第七模块笔记(Web开发进阶之Django数据库操作)相关的知识,希望对你有一定的参考价值。

4、Django ORM

4.1、连接数据库

创建Django工程后运行该工程,会在工程根目录下创建db.sqlite3文件,为Django自带的sqlite3数据库(Django自带的功能也需要数据库支持),如果没有在settings.py文件中进行配置的话,数据将会保存在该数据库中。

Django使用MySQL:

# 修改settings.py中DATABASES = {}的内容为
DATABASES = {
    default: {
    ENGINE: django.db.backends.mysql,
    NAME:数据库名称,
    USER: 用户名,
    PASSWORD: 密码,
    HOST: 主机,
    PORT: 端口,
    }
}

# Python 3.x中让Django使用pymysql连接MySQL,在工程配置目录下的__init__.py文件中添加如下内容
import pymysql
pymysql.install_as_MySQLdb()

4.2、创建表结构

在Django中定义一个类来自动生成表结构,类写在APP目录下的models.py文件中。

要使models.py文件生效,需要先在settings.py文件中注册该APP:

# 在settings.py中的INSTALLED_APPS = 下添加
‘APP名’,

在models.py文件下编写:

from django.db import models


class Foo(models.Model):
    xxx = models.字段类型(参数)

以下为具体字段类型:

# 自增
AutoField(Field),int自增列,必须填入参数 primary_key=True
BigAutoField(AutoField),bigint自增列,必须填入参数 primary_key=True
# 注:当model中如果没有自增列,则自动会创建一个列名为id的列

# 数字
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中提供验证机制
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),二进制类型

以下为具体参数:

null                 -> 是否为空
default              -> 默认值
primary_key          -> 主键
db_column            -> 列名
db_index             -> 索引
unique               -> 唯一索引
unique_for_date      -> 基于日期的唯一索引
unique_for_month     -> 基于月份的唯一索引
unique_for_year      -> 基于年份的唯一索引
auto_now             -> 创建时自动生成时间
auto_now_add         -> 更新时自动更新时间,只能在使用obj.save()更新时生效

# 以下参数应用与Django Admin中
choices              -> 显示下拉框,避免连表查询
blank                -> 是否可以为空
verbose_name         -> 显示字段中文
editable             -> 是否可以编辑
error_messages       -> 错误信息
help_text            -> 提示
validators           -> 自定义错误信息

表结构创建完成后,使用以下命令写入数据库:

python manage.py makemigrations
python manage.py migrate

4.3、在表中添加数据

from APP import models
models.类名.objects.create(xxx= ,...)

dict = {}
models.类名.objects.create(**dict)

obj = models.类名(xxx= ,...)
obj.save()

4.4、查询数据

查询全部数据

from APP import models

# 有以下三种方式可以查询全部数据

models.类名.objects.all()
# 获取一个QuerySet(类似列表),内部元素都是对象

models.类名.objects.all().values(字段, ...)
# 获取一个QuerySet,内部元素都是字典

models.类名.objects.all().values_list(字段, ...)
# 获取一个QuerySet,内部元素都是元组

条件查询

from APP import models

models.类名.objects.filter(条件1, 条件2, ...)
# 条件查询

models.类名.objects.filter(条件1, 条件2, ...).first()
# 查询符合条件的第一条记录

dict = {条件1, 条件2, ...}
models.类名.objects.filter(**dict)

# 条件表达式
    - = ,等于
    - __gt = ,大于
    - __lt = ,小于
    - __gte = ,大于等于
    - __lte = , 小于等于

models.类名.objects.get(条件1, 条件2, ...)
# 使用该方式获取时数据不存在会报错

4.5、修改和删除数据

要进行修改和删除操作,都必须先查询到数据,然后进行下一步操作。

from APP import models

# 修改,两种方式
models.类名.objects.filter(条件).update(xxx=‘‘, ...)

dict = {}
models.类名.objects.filter(条件).update(**dict)

obj = models.类名.objects.filter(条件)
obj.xxx = 新值
obj.save()

# 删除
models.类名.objects.filter(条件).delete()

4.6、表间一对多关联操作

from APP import models


class Foo1(models.Model):
    foo1_xxx = models.字段类型()


class Foo2(models.Model):
    foo2_xxx = models.字段类型()
    xxx1 = models.ForeignKey(to = "Foo1", to_field = "id")
    # 也可以简写为xxx1 = models.ForeignKey("Foo1"),将自动与表的主键关联

# Foo2表中将生成xxx1_id列,关联Foo1表的id列,而此处的xxx1为一个包含Foo1表内容的对象
# 通过Foo2表查询Foo1中的内容
obj = models.Foo2.objects.filter(id="1")
obj.xxx1.foo1_xxx

可以使用__进行跨表查询:

models.Foo2.objects.all().values(xxx1__foo1_xxx)

4.7、表间多对多关联操作

为了实现两张表之间的多对多关联,必须借助第三张表实现;用以下两种方式创建两张表间的多对多关联:

from APP import models

# 自定义关系表
class Foo1(models.Model):
    foo1_xxx = models.字段类型()


class Foo2(models.Model):
    foo2_xxx = models.字段类型()


class Foo1ToFoo2(models.Model):
    f1 = models.ForeignKey(to="Foo1", to_field="id")
    f2 = models.ForeignKey(to="Foo2", to_field="id")
    # 通过创建两个ForeignKey来关联两个表
# 使用该方式的好处是可定制性强,在第三张表中可以自定义字段


# Django自动创建关系表
class Foo1(models.Model):
    foo1_xxx = models.字段类型()


class Foo2(models.Model):
    foo2_xxx = models.字段类型()
    x = models.ManyToManyField("Foo1")
# 使用该方式Django将自动维护关联的第三张表,用户无法对该表进行操作

Django自动创建关系表情况下的第三张表操作:

from APP import models

obj = models.Foo2.objects.filter(id="1")

# 添加
obj.x.add(n)
obj.x.add(n, n1, ...)
obj.x.add(*[n, n1, ...])

# 删除
obj.x.remove(n)
obj.x.remove(n, n1, ...)
obj.x.remove(*[n, n1, ...])

# 清除所有
obj.x.clear()

# 重新设置值
obj.x.set([n, n1, ...])

# 查询
obj.x.all()
obj.x.all().filter(xxx="...")

以上是关于Python学习----第七模块笔记(Web开发进阶之Django数据库操作)的主要内容,如果未能解决你的问题,请参考以下文章

python学习笔记:第七天(函数)

Java开发进大厂面试必备技能,图文详解!

python学习笔记之socket(第七天)

Python第七周 学习笔记

Python 学习之《Learn Python3 The Hard Way 》第七部分学习笔记

Python第七周 学习笔记