Django-- (三) Django数据库操作

本文详细介绍了Django的ORM机制,包括数据库建模、字段类型、数据库配置、数据迁移以及ORM操作数据库的方法,如增删改查。此外,还涵盖了Django中的一对一、一对多和多对多关系操作,以及MVC和MVT架构模式的应用。通过实例展示了如何使用Django构建数据库驱动的电商应用。
摘要由CSDN通过智能技术生成

1、Django数据库

Django 非常适合构建数据库驱动型网站,它提供了简单而强大的工具(ORM),易于使用 Python 执行数据库查询。

2、ORM介绍

Object Relational Mapping,简称ORM(对象关系映射)将面向对象语言程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式(对象)转换到另外一种形式(数据库表格)。

3、数据库建模

Django的数据库模型,必须要在App当中的models中创建。

3.1 模型的搭建

例如,以电商的实体关系建模,模型如下:

默认情况下,Django会给每一个模型添加下面字段

id = models.AutoField(primary_key=True)

模型的搭建

from django.db import models


# Create your models here.

class Seller(models.Model):
    """seller卖家"""
    name = models.CharField(max_length=64)
    password = models.CharField(max_length=64)
    nickname = models.CharField(max_length=64, null=True)
    gender = models.CharField(max_length=64, null=True)
    age = models.IntegerField(null=True)
    # ImageField图片路径
    picture = models.ImageField(null=True)
    phone = models.CharField(max_length=64, null=True)
    address = models.CharField(max_length=64, null=True)
    # EmailField自带邮箱格式验证
    email = models.EmailField(max_length=64, null=True)
    createtime = models.DateTimeField(null=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = "seller"  # 指定表名


class Store(models.Model):
    """store店铺"""
    name = models.CharField(max_length=64)
    description = models.TextField(null=True)
    address = models.CharField(max_length=64)
    picture = models.ImageField(null=True)
    seller = models.OneToOneField(to=Seller, on_delete=models.CASCADE)  # 一对一关系
    goodstypes = models.ManyToManyField(to="GoodsType", db_table="store_goodstype")  # db_table指定中间表的名字

    def __str__(self):
        return self.name

    class Meta:
        db_table = "store"  # 指定表名


class GoodsType(models.Model):
    """store店铺"""
    name = models.CharField(max_length=64)
    description = models.TextField(null=True)
    picture = models.ImageField(null=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = "goodstype"  # 指定表名


class Goods(models.Model):
    """store店铺"""
    name = models.CharField(max_length=64)
    price = models.IntegerField(null=True)
    number = models.IntegerField(null=True)
    sale = models.IntegerField(null=True)
    picture = models.ImageField(null=True)
    description = models.TextField(null=True)
    detail = models.TextField(null=True)
    producttime = models.DateField(null=True)
    shelfife = models.IntegerField(null=True)
    unite = models.CharField(max_length=64)
    # 冗余,方便查询商品与店铺
    store_id = models.IntegerField(null=True)
    goodstype = models.ForeignKey(to=GoodsType, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

    class Meta:
        db_table = "goods"  # 指定表名

ImageField字段需要安装pillow包,未安装则会报错

pip install pillow

3.2 常用的字段
字段名称字段描述
CharField字符串类型,必须设置max_length
IntergerField整数类型
FloatField小数类型
EmailField邮件格式的字符串
TextField文本类型
DateField日期 年月日
DateTimeField时间 年月日时分秒
FileField文件类型 特殊类型,可以保存文件路径同时自动上传文件 必须设置upload_to上传到媒体路径下的位置
ImageField图片文件类型 特殊类型,可以保存文件路径同时自动上传文件,upload_to上传到媒体路径下的位置,需要在settings中配置媒体路径。
电话类型必须是美国座机格式的电话号码

注:媒体路径的配置

3.3 常用的字段参数
参数名称参数描述
verbose_name别名,在后台可以使用
default默认值
unique不可以重复
blank可以为空,常用于字符串
null可以为null,常用于数字,和时间
max_length字符类似的长度
upload_to文件上传地址
Auto_now默认当前时间

4、数据库配置

4.1 配置sqlite3数据库

Django默认配置的就是sqlite3数据库,配置信息如下:

4.2 配置mysql数据库
4.2.1 编写配置信息

4.2.2 下载pymysql
pip install pymysql

注意:Python2 版本中使用的是MySQLdb的模块,现在用的是Python3版本,由 PyMySQL取代

在项目包下安装pymysql,兼容mysqldb

排错,由于Django2.2.1 和 PyMySQL 不兼容,需要修改源码

进入base.py,注释版本判断

修改版本判断后,因python3中字符串没有decode方法,,operations.py报错,把decode修改为encode

4.3 数据迁移

在Django 的ORM操作当中,数据库操作需要进行命令同步

4.3.1 检查

python manage.py check

4.3.2 生成映射文件

python manage.py makemigrations

4.3.3 迁移到数据库中

python manage.py migrate

5、ORM操作数据库

django可以通过命令开启命令行模式对模型进行操作,命令如下:

python manage.py shell

但默认的命令行并不支持tab补全操作,我们可以安装ipython来实现在命令行模式中使用tab补全操作。

pip install ipython
5.1 增
In [2]: s = Seller()
In [3]: s.name = "laowang"
In [4]: s.password = "123"
In [5]: s.save()

In [8]: Seller.objects.create(
   ...: name="隔壁",
   ...: password="123",
   ...: age=18)
Out[8]: <Seller: Seller object (2)>
5.2 删
In [9]: Seller.objects.get(id=1)
Out[9]: <Seller: Seller object (1)>

In [10]: Seller.objects.get(pk=1)
Out[10]: <Seller: Seller object (1)>

In [11]: s = Seller.objects.get(pk=1)

In [12]: s.delete()
Out[12]: (1, {'store.Seller': 1})
5.3 改
In [14]: s = Seller.objects.get(id=2)

In [15]: s.name = "laowang"

In [16]: s.save()  # 数据的更新和保存都是用save,根据id判断,有数据就更新,没有则添加
5.4 查
5.4.1 get

返回与所给筛选条件相匹配的对象。
返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
返回具体的某个模型类的对象,而不是QuerySet列表对象。

In [9]: Seller.objects.get(id=1)
Out[9]: <Seller: Seller object (1)>

In [10]: Seller.objects.get(pk=1)
Out[10]: <Seller: Seller object (1)>
5.4.2 filter

返回包含了与所给筛选条件相匹配的对象,返回 QuerySet 列表对象。获取对象时,通过索引或者遍历可以传入多个关键字,底层的sql 使用and 来连接多个条件

In [2]: Seller.objects.filter(gender="男")
Out[2]: <QuerySet [<Seller: Seller object (2)>,<Seller: Seller object (10)>]>

Seller.objects.filter(gender="男",age__gt=30)
Out[3]: <QuerySet []>
5.4.3 all

获取所有

In [4]: Seller.objects.all()
5.4.4 order_by

排序

In [5]: Seller.objects.order_by("id")  # 排序

In [6]: Seller.objects.order_by("-id")  # 排倒序
5.4.5 first,last

获取第一个,获取最后一个。

In [7]: Seller.objects.filter(gender="男").first()
Out[7]: <Seller: Seller object (2)>

In [8]: Seller.objects.filter(gender="男").last()
Out[8]: <Seller: Seller object (10)>
5.4.6 双下划线查询
条件描述举例
__gt大于Seller.objects.filter(id__gt=4)
__lt小于Seller.objects.filter(id__lt=2)
__gte大等于Seller.objects.filter(id__gte=2)
__lte小等于Seller.objects.filter(id__lte=2)
__contains模糊查询 相当于sql like(%keywords%)Seller.objects.filter(phone__contains=‘153’)
__in判断在范围Seller.objects.filter(id__in=[1,2,3])
__isnull判断为空Seller.objects.filter(phone__isnull=False)
__startswith获取以指定内容开头的记录Seller.objects.filter(phone__startswith=‘13’)
5.4.7 聚合查
from django.db.models import Sum,Avg,Max,Min,Count

In [10]: Seller.objects.filter(gender="男").aggregate(Count("id"))
Out[10]: {'id__count': 5}

In [11]: Seller.objects.all().aggregate(Avg("age"))
Out[11]: {'age__avg': 22.6}
5.4.8 分组查
In [12]: Seller.objects.all().values("gender").annotate(Count("id"))
Out[12]: <QuerySet [{'gender': '女', 'id__count': 5}, {'gender': '男', 'id__count': 5}]>
5.4.9 F查询

F()的实例引用一个模型字段。可以比较同一个模型实例中的两个字段。

查询id小于年龄的数据

from django.db.models import F

In [15]: Seller.objects.filter(pk__gt=F("age"))
Out[15]: <QuerySet [<Seller: Seller object (10)>]>
5.4.10 Q查询

filter() 等的关键字参数指定的条件是并联在一起的,如果需要执行更复杂的查询(例如,使用or语句查询),可以使用 Q 对象。

符号描述
|
&
~
In [18]: from django.db.models import Q

In [19]: Seller.objects.filter(Q(age__gt=20)|Q(gender="男"))  # or
Out[19]: <QuerySet [<Seller: Seller object (1)>, <Seller: Seller object (3)>]>

In [20]: Seller.objects.filter(Q(age__gt=20)&Q(gender="男"))  # and
Out[20]: <QuerySet [<Seller: Seller object (2)>]>
 
In [21]: Seller.objects.filter(~Q(gender="男"))  # not
Out[21]: <QuerySet [<Seller: Seller object (1)>, <Seller: Seller object (3)>]>
5.4.11 分页

Django本身有携带分页函数,可以自动分页,但是也有限制查的方法,使用索引,因为Django ORM查询的结果集是一个QueryList(类列表对象),所以可以用索引。

In [22]: Seller.objects.filter(gender="男")[:2]
Out[22]: <QuerySet [<Seller: Seller object (1)>, <Seller: Seller object (3)>]>

6、关系操作

6.1 一对一关系
6.1.1 增
In [6]: s = Seller.objects.create(
   ...: name="laowang",
   ...: password="123")

In [7]: store = Store.objects.create(
   ...: name="老王水饺店",
   ...: seller=s)
6.1.2 删
In [9]: s.delete()
Out[9]: (2, {'store.Store': 1, 'store.Seller': 1})
6.1.3 改

从外键处添加

In [10]: store = Store.objects.get(id=1)

In [11]: s = Seller.objects.get(id=11)

In [12]: store.seller = s

In [13]: store.save()
6.1.4 查
In [10]: store = Store.objects.get(id=1)

In [11]: s = Seller.objects.get(id=11)

In [16]: s
Out[16]: <Seller: laowang>

In [17]: store
Out[17]: <Store: 星星1号店>

In [18]: store.seller
Out[18]: <Seller: laowang>

In [19]: store.seller_id
Out[19]: 11

In [20]: store.seller.id
Out[20]: 11
6.2 一对多关系

使用Foreign Key,在一方(GoodsType)会自动增加一个属性goods_set,方便一方查询多个数据

foreign key 和manytomany 集合属性,有add新增,remove移除,clear清除,all()查所有返回QuerySet,还有其他的,使用dir查看。

字段参数:

字段参数描述
to设置要关联的表
to_field设置要关联的表的字段
on_delete当删除关联表中的数据时,当前表与其关联的行的行为
6.2.1 增

给商品类型为3的添加一个商品

In [2]: goodstype = GoodsType.objects.get(id=3)

In [3]: goods = Goods.objects.create(name="辣条",goodstype=goodstype)

In [4]: goods
Out[4]: <Goods: 辣条>

# add添加
        
In [74]: goodstype = GoodsType.objects.get(id=3)

In [75]: g = Goods.objects.create(name="螺蛳粉")

In [76]: goodstype.goods_set.add(g)

In [77]: goodstype.save()

6.2.2 删

删除商品类型3

In [5]: goodstype = GoodsType.objects.get(id=3)

In [6]: goodstype.delete()
Out[6]: (5, {'store.Store_goodstypes': 0, 'store.Goods': 4, 'store.GoodsType': 1})
6.2.3 改

将id是3的商品的类型改为2类型

goods = Goods.objects.get(id=3)
goodstype = GoodsType.objects.get(id=2)
goods.goodstype = goodstype
goods.save()
5.2.4 查

查询类型2的下的所有商品

In [15]: goodstype = GoodsType.objects.get(id=2)

In [16]: goodstype.goods_set.all()
Out[16]: <QuerySet [<Goods: 燕塘牛奶>, <Goods: 可口可乐>, <Goods: 雪碧>]>
6.3 多对多关系

店铺和商品类型多对多,使用ManyToMany。
任选1方(Store)加ManyToMany,会在另一方(GoodsType)自动增加一个属性store_set,goodstype可以根据这个属性来查询该类型下的所有商品。

In [21]: goodstype = GoodsType.objects.get(id=1)

In [22]: goodstype.store_set.all()
Out[22]: <QuerySet [<Store: 星星1号店>, <Store: 星星2号店>, <Store: 星星4号店>]>
6.3.1 增

新增一个商品类型,增加到店铺1中

In [23]: gt = GoodsType.objects.create(name="药品")

In [24]: gt
Out[24]: <GoodsType: 药品>

In [25]: s = Store.objects.get(id=1)

In [26]: s.goodstypes.add(gt)

In [27]: s.save()
6.3.2 删

删除id为1的店铺

In [29]: s = Store.objects.get(id=1)

In [30]: s.delete()
Out[30]: (3, {'store.Store_goodstypes': 2, 'store.Store': 1})
6.3.3 改

id为2的店铺新增商品类型2,删除商品类型1

In [44]: s = Store.objects.get(id=2)

In [45]: gt1 = GoodsType.objects.get(id=1)

In [46]: gt2 = GoodsType.objects.get(id=2)

In [47]: s.goodstypes.add(gt2)

In [48]: s.goodstypes.remove(gt1)

In [49]: s.save()
6.3.4 查

查询id为2的店铺下所有的商品类型

In [31]: s = Store.objects.get(id=2)
In [32]: s
Out[32]: <Store: 星星2号店>

In [33]: s.goodstypes.all()
Out[33]: <QuerySet [<GoodsType: 牛奶类>]>

查询类型1 的商品在哪家店铺出售

In [83]: gt = GoodsType.objects.get(id=1)

In [84]: gt.store_set.all()
Out[84]: <QuerySet [<Store: 星星1号店>, <Store: 星星4号店>]>

7、MVC和MVT架构模式

7.1 MVC架构模式

MVC全称Model View Controller,分为三个基本部分:模型Model、视图View和控制器Controller。

Model,模型,代表数据存取层,和数据库进行交互。
View ,视图,产生HTML页面,代表的是系统中选择显示什么和怎么显示的部分。
Controller,控制器, 接收请求,进行处理,与M和V进行交互,返回响应。

7.2 MVT架构模式

Django框架借鉴了MVC的思想,也分成三个部分来降低各个部分之间的耦合性,不同之处是Django框架分为三部分:Model模型、Template模板、View视图,这就是MVT模型。

Model(模型):负责业务对象与数据库的对象(ORM)。
View(视图):负责业务逻辑,并在适当的时候调用Model和Template。
Template(模版):负责如何把页面展示给用户。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值