文章目录

  • 1 什么是数据库的CRUD
  • 2 Django 定义ORM模型
  • 3 Django shell
  • 4 Django 使用ORM实现数据新增
  • 4.1 使用save()保存数据
  • 4.2 使用create()新增数据
  • 4.3 使用bulk_create()批量新增数据
  • 外键关联数据的插入
  • 5 Django 使用ORM实现简单查询
  • 使用all查询所有数据
  • 6 Django 使用ORM实现数据修改
  • 7 Django 使用ORM实现删除操作
  • 使用ORM物理删除数据
  • 逻辑删除vs物理删除


1 什么是数据库的CRUD

  • Create——新增
  • Read——读、查询
  • Update——修改
  • Delete——删除
  • 句话概括:数据库的增删改查

2 Django 定义ORM模型

  • 新建模块
python manage.py startapp accounts

python和django的对应的版本 python django orm_数据库

from django.db import models


class CommonModel(models.Model):
    """ 自定义模型的基类 """
    created_at = models.DateTimeField('添加时间', auto_now_add=True)
    updated_at = models.DateTimeField('最后修改时间', auto_now=True)

    class Meta:
        # 抽象类,这个类,并不会生成对应的数据库表
        abstract = True


class User(CommonModel):
    """ 用户基本信息 """
    USER_STATUS = (
        (1, '正常'),
        (0, '删除'),
    )
    username = models.CharField('用户名', max_length=128, unique=True)
    password = models.CharField('密码', max_length=256)
    nickname = models.CharField('用户昵称', max_length=256, null=True, blank=True)
    avatar = models.ImageField('用户头像', upload_to='avatar', null=True, blank=True)
    status = models.SmallIntegerField('用户状态', default=1, choices=USER_STATUS)
    is_super = models.BooleanField('是否为超级用户', default=False)
    created_at = models.DateTimeField('注册时间', auto_now_add=True)
    updated_at = models.DateTimeField('更新时间', auto_now=True)

    class Meta:
        db_table = 'accounts_user'


class UserProfile(CommonModel):
    """ 用户详细信息 """
    SEX_CHOICES = (
        (0, '未知'),
        (1, '男'),
        (2, '女'),
    )
    user = models.OneToOneField(User, verbose_name='关联用户',
                                related_name='profile',
                                on_delete=models.CASCADE)
    username = models.CharField('用户名', max_length=128, unique=True)
    real_name = models.CharField('真实姓名', max_length=128, null=True, blank=True)
    sex = models.SmallIntegerField('用户性别', default=0, choices=SEX_CHOICES)
    maxim = models.CharField('用户格言', max_length=128, null=True, blank=True)
    address = models.CharField('用户地址', max_length=128, null=True, blank=True)

    class Meta:
        db_table = 'accounts_user_profile'


class LoginHistory(models.Model):
    """ 用户的登录历史 """
    user = models.ForeignKey(User, related_name='login_history_list',
                             on_delete=models.CASCADE,
                             verbose_name='关联的用户')
    username = models.CharField('用户名', max_length=128)
    login_type = models.CharField('账号平台', max_length=128)
    ip = models.CharField('IP地址', max_length=32, default='')
    ua = models.CharField('登录来源', max_length=128, default='')
    created_at = models.DateTimeField('登录时间', auto_now_add=True)

    class Meta:
        db_table = 'accounts_login_history'
        ordering = ['-created_at']

python和django的对应的版本 python django orm_mysql_02

结果如下:

python和django的对应的版本 python django orm_python和django的对应的版本_03

python和django的对应的版本 python django orm_django_04

python和django的对应的版本 python django orm_django_05

3 Django shell

  • 从控制台(terminal)进入
  • python manage.py shell

  • 从pyCharm的PythonConsole进入

4 Django 使用ORM实现数据新增

4.1 使用save()保存数据

示例代码:

user_obj = User(username='admin',
               password='password')
user_obj.save()

运行代码:

python和django的对应的版本 python django orm_python和django的对应的版本_06

数据库已经新增:

python和django的对应的版本 python django orm_python和django的对应的版本_07

4.2 使用create()新增数据

  • 示例代码
user_obj = User.objets.create(username='admin', password='password')

user_obj.pk

运行代码:

python和django的对应的版本 python django orm_mysql_08

数据库已经新增:

python和django的对应的版本 python django orm_python_09

4.3 使用bulk_create()批量新增数据

  • 示例代码
user1 = User(username='admin', password='password')
user2 = User(username='manager', password='password')
user_list = [user1,user2]
User.objects.bulk_create(user_list)

演示:

python和django的对应的版本 python django orm_mysql_10

结果:

python和django的对应的版本 python django orm_数据库_11

外键关联数据的插入

  • 示例代码
user = User(username='admin', password='password')
LoginHistory.objects.create(user=user, *args, **kwargs)

执行代码:

python和django的对应的版本 python django orm_mysql_12

效果:

python和django的对应的版本 python django orm_数据库_13

执行代码:

python和django的对应的版本 python django orm_python和django的对应的版本_14

效果:

python和django的对应的版本 python django orm_mysql_15

5 Django 使用ORM实现简单查询

查询单条数据:

  • get(**kwargs)
  • 按照查询条件返回单条数据
User.objects.get(pk=1)
user_obj.id
  • latest(*fields)/earliest(*fields)
  • 返回最晚、最早的一条记录

编程技巧:

  • 注意异常的处理
  • DoesNotExist:查询的记录不存在
  • MultipleObjectsReturned:查询的记录有多条
  • 若有则返回,若无则创建后返回
object,created = User.objects.get_or_create(*args, **kwargs)
  • 如果没有则触发404异常
  • get_object_or_404(klass, *args, **kwargs)
  • first()/last()
  • 返回第一条、最后一条记录

使用all查询所有数据

  • 示例代码
User.objects.all()
user_obj
  • 打印模型字符串 __str__()的使用
User.objects.all()
user_obj
def __str__(self):
    return 'User:{}'.format(self.username)

注意记录不存在/记录有多条时的异常处理

6 Django 使用ORM实现数据修改

  • 使用save()修改单条数据
user_obj = User.objects.get(pk=1)
user_obj.nickname = '管理员'
user_obj.save()
  • 使用update()批量修改数据
  • 方式一:统一修改
  • SQL示例:UPDATE table SET column='ABC'
count = User.objects.all().update(*args, **kwargs)
count
  • 已全部更新
  • 注意不能修改外键关联的对象
  • 如:update(user_nickname='李四')
  • 方式二:循环逐一修改
for user in user_list:
    user.nickname = '李四'
    user.save()
  • 使用bulk_update()批量修改数据
  • bulk_update(objs, fields, batch_size=None)
  • objs:需要修改的记录列表
  • fields:指定需要修改的字段
  • batch_size:每次提交多少条记录进行修改

7 Django 使用ORM实现删除操作

使用ORM物理删除数据

  • 使用模型的delete()删除数据
  • 删除单条数据
user_obj = User.objects.get(pk=1)
user_obj.delete()
  • 因为是这样定义的:
  • 删除多条数据(批量删除)
User.objects.all().delete()

逻辑删除vs物理删除

  • 物理删除
  • 将数据从数据库干掉
  • 干掉了就不占磁盘空间了
  • 干掉了就找不回来了
  • 逻辑删除
  • 将数据标记删除
  • 删除后还占磁盘空间
  • 删除后还可以恢复
  • 删除后通过查询条件不展示给用户