三、python Django ORM操作数据库[增删改查、一对多等、自定义脚本]

django 3.2.13

一、数据库初始化

1.配置

目录:项目目录/setting.py
写入配置:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql', 
    	'NAME': 'postgres', # 数据库名称
        'USER': 'postgres', # 登录数据库的用户名
        'PASSWORD': ' ',# 登录数据库的密码
        'HOST': '127.0.0.1', # 数据库服务器的主机地址(默认本机为127.0.0.1)
        'PORT': '5432', # 数据库服务的端口号(默认为5432)
    }
}

2.创建模型

目录:项目目录/app目录/models.py

class Question(models.Model):
	question_text = models.CharField(max_length=200)
	pub_date = models.DateTimeField('date published')
	def __str__(self):
		return self.question_text

class Choice(models.Model):
	question = models.ForeignKey(Question, on_delete=models.CASCADE)
	choice_text = models.CharField(max_length=200)
	votes = models.IntegerField(default=0)

数据类型图:
在这里插入图片描述
数据类型参数:
在这里插入图片描述
注意__str__方法用于返回对象的描述信息,如果不使用__str__方法,直接print,或者return,返回的是对象的内存地址

zhangsan = Student("张", 2200)
print(zhangsan) # 如果Student这个class类,没有写__str__方法,输出的是内存地址,但是加上__str__就是值

3.数据库内容创建(迁移)

前要:第一次迁移前看一下user表结构更改

  1. 生成脚本文件:python3 manage.py makemigrations
  2. 执行脚本文件(操作数据库):python3 manage.py migrate

注意:Ⅰ.比如数据库表单已经生成,需要删除一个字段可以直接再次执行上诉命令;Ⅱ.添加字段必须要为其设置默认值,否则django会进行询问(可写入默认值,可退出该操作)

二、自定义脚本

首先:pip install django-extensions
其次:写入setting.py 文件中的INSTALLED_APPS中添加django_extensions
创建:文件add.py
编辑自定义脚本如下:

import random
import string

from Main.models import Like




def generate_random_codes():
    for obj in Like.objects.filter(code=None):

        obj.code = code
        obj.save()


generate_random_codes()

执行:python manage.py runscript add.py

三、增删改查

具体:书Django Web应用开发实战p161开始

1.增

from .models import Article
Article.objects.create(title="My first article", body="My first article body")

2.删

2.1 删一条
from .models import Article
Article.objects.get(title="java").delete() 
2.2 删多条(条件满足的)
from .models import Article
Article.objects.filter(title="java").delete() 
2.3 on_delete删除模式

写法:on_delete=models.CASCADE

参数:

  1. PROTECT:如果删除的数据设有外键且关联其它数据表,就提示删除错误,其实在外键上就是不许删除
  2. CASCADE:级联删除,删除与主键关联表的数据,主键所在表的内容也会被删除反之则不会
  3. SET_NULL:置空模式,删除的时候,外键字段被设置为空,前提就是null=True
  4. SET_DEFAULT:置默认值,删除的时候,外键字段设置为默认值,前提就是default=‘默认值’(此时不能出现null=True,一对一特殊关系慎用)

3.改

3.1 改一条
# get方式不能用update
from .models import Article
a = Article.objects.get(id=1)
a.foreign_id=3
a.save()
3.2 改多条(条件满足的)
from .models import Article
Article.objects.filter(title='java').update(title='django')

4.查

4.1 查方法

4.1.1 查全部
from .models import Article
Article.objects.all() 
4.1.2 查单个
from .models import Article
article = Article.objects.get(id=1)
article = Article.objects.filter(id=1).first() # 没有返回None
4.1.3 查多个
from .models import Article
article = Article.objects.filter(name='jack')
4.1.4 数量查询
from .models import Article
article = Article.objects.filter(name='jack').count()
4.1.5 多个条件
4.1.5.1 and
from .models import Article
article = Article.objects.filter(name='jack',id=5)
4.1.5.2 or
from .models import Article
from django.db.models import Q
article = Article.objects.filter(Q(name='jack')|Q(passwd='5963'))
4.1.5.3 不等于查询
from .models import Article
article = Article.objects.filter(~Q(name='jack'))

4.2 谓语查询[模糊查询、大小、范围]

4.2.1 模糊查询
# 关键__contains表示模糊查询
Teacher.objects.filter(name__contains='8') 
4.2.2 指定开头结尾
# 表示以9开头
a = Teacher.objects.filter(name__startswith='9') 
# 表示以9结尾
a = Teacher.objects.filter(name__endswith='9') 
4.2.3 大小比较
# 大于8
a = Teacher.objects.filter(id__gt=8)
# 大于等于8
a = Teacher.objects.filter(id__gte=8) 
# 小于8
a = Teacher.objects.filter(id__lt=8) 
# 小于等于8
a = Teacher.objects.filter(id__lte=8)
4.2.4 字段在某列表
# 字段在某个列表中 __in=[8,9,10],下面表示,id号在[8,9,10]列表里面,通俗讲此处就是id=8,id=9,id=10的情况
a = Teacher.objects.filter(id__in=[8,9,10]) 
4.2.5 数字字段在某个范围内
# id在8-15之间的都取出
a = Teacher.objects.filter(id__range=(8,15))

4.3 F对象

4.3.1 字段自增

解释:普通的自增什么的都需要先提取出来再增加,明显浪费资源,使用此方法,数据库直接会操作

# 让id=8这个数据里面的time字段增加100
from django.db.models import F 
Student.objects.filter(id=8).update(time=F('time')+100)
4.3.2 两个数据比较
# 对比所有信息,取出其中id号小于time对应内容的数据
from django.db.models import F 
Student.objects.filter(id__lt=F('time')) 

4.4 聚合查询

4.4.1 聚合不分组

解释:也就是全部都在一起来算,返回的数据为字典无需序列化

from django.db.models import Avg,Max,Min,Count,Sum # 统计平均值,最大值,最小值,数量,和
Student.objects.aggregate(sum=Count('time')) # {'sum': 345354345}

Student.objects.aggregate(sum=Max('time')) # {'sum': 3}

4.4.2 聚合分组

解释:某些数据来进行运算,返回的数据为字典无需序列化

from django.db.models import Avg,Max,Min,Count,Sum
# 格式:某个组.aggregate(sum=Count('time'))
Student.objects.filter(id__lt=F('time')).aggregate(sum=Count('time')) # {'sum': 3}



四、一对一、一对多、多对多

在这里插入图片描述

知识点:

  1. 正向查询:Info.objects.all()[0].foreign #info是有外键的表,foreign是定义的外键参数名
  2. 反向查询:
# 一对一
>>> a = User.objects.all()[0] # User是外键关联表
>>> a.back #back是设置的外键属性related_name
<InfoTwo: 1>
# 一对多
>>> a = Father.objects.all()[0]# Teacher是外键关联表
>>> a.back.all() #back是设置的外键属性related_name
<QuerySet [<Student: 563>, <Student: 563>]>

1.一对一

关系:人的身份证与人的关系,一一对应不可重复
关键概念:

  1. 外键:其也属于一个键值,是真实在表格里面存在的,外键对应的内容是另一个表的主键
  2. 正向查询:在外键所在表查询到,与外键关联的表内容
  3. 反向查询:在与外键关联的表,查询到外键所在表内容

知识点:

  1. OneToOneField:Info= models.OneToOneField(User, on_delete=models.CASCADE,related_name=‘back’) # 用于一对一查询

设置外键:

  1. Info.objects.create(id=100,passwd='00',time=12,foreign_id=4) #确保关联表已经有数据关键是注意这个名字,与models.py里面定义的不一样
from django.db import models


# Create your models here.
class User(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name # 必须是字符串


class Info(models.Model):
    id = models.AutoField(primary_key=True)
    passwd = models.CharField(max_length=30)
    time = models.IntegerField()
    foreign = models.OneToOneField(User, on_delete=models.CASCADE,related_name=‘back’) # on_delete解释看二、增删改查 2.删

    def __str__(self):
        return self.passwd # 必须是字符串

2.一对多

关系:父亲与孩子的关系,一个父亲有多个孩子,一个孩子只有一个父亲

知识点:

  1. ForeignKey:foreign = models.ForeignKey(Teacher, on_delete=models.CASCADE,related_name=‘back’)

设置外键:

  1. Son.objects.create(id=100,passwd='00',time=12,foreign_id=4) #确保关联表已经有数据关键是注意这个名字,与models.py里面定义的不一样
class Father(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=20)

    def __str__(self):
        return self.name


class Son(models.Model):
    id = models.AutoField(primary_key=True)
    passwd = models.CharField(max_length=30)
    time = models.IntegerField()
    foreign = models.ForeignKey(Teacher, on_delete=models.CASCADE,related_name=‘back’)# on_delete解释看二、增删改查 2.删

    def __str__(self):
        return self.passwd

3.多对多

关系:老师和学生的关系,一个老师有多个学生,一个学生有多个老师

原理:多对多通过创建中间表格确定对应关系

设置外键:

  1. 初始化:Student.objects.get(id=1).foreign.set([1,2,3])# 1,2,3默认都是与Student关联表的主键(set的特点:此例设置的Teacher的id的1,2,3关联到Student的id=1上面。如果原关系为1,2会直接改为1,2,3;如果原关系为1,2,3,4,5也会直接改为1,2,3) 总结:既能增加又能删除
  2. 增加:Student.objects.get(id=1).foreign.add(1,2)# 1,2默认都是与Student关联表的主键
  3. 删除:Student.objects.get(id=1).foreign.remove(1)# 1默认都是与Student关联表的主键
  4. 清空关系:Student.objects.get(id=1).foreign.clear()
class Teacher(models.Model):
    id = models.AutoField()
    name = models.CharField(max_length=20, primary_key=True)

    def __str__(self):
        return self.name


class Student(models.Model):
    id = models.AutoField(primary_key=True)
    passwd = models.CharField(max_length=30)
    time = models.IntegerField()
    foreign = models.ManyToManyField(Father, on_delete=models.CASCADE, related_name='back')

    def __str__(self):
        return self.passwd
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值