Django数据库——外键与查询条件

前提:
如果你用的是php_study,你需要在设置的mysql的配置文件里更改默认的数据库引擎,设置为InnoDB,InnoDB支持数据库的外键约束。
在这里插入图片描述

设置外键

通过models.ForeignKey来设置外键,他有两个必须要传的参数

  • to: 外键连接的表
  • on_delete: 外键删除后,相关数据的操作方式
from django.db import models

class Article(models.Model):
	name = models.CharField(max_length=20)
	author = models.ForeignKey('Author', on_delete=models.CASCADE, null=True)

class Author(models.Model):
	name = models.CharField(max_length=20)

查询操作

def search(request):
	article = Article.objects.filter(name='Python')[0]
	# 通过外键直接获取
	author = article.author.name
	print('Python的作者是:', author)

外键删除操作

在上面我们设置的外键删除操作是on_delete = models.CASCADE,即级联删除。也就是说如果外键对应的数据被删除了,那么这条数据也会被删除。

下面列举了一些其他的比较常用的删除操作:

  • PROTECT:受保护,即只要有外键连接了这条数据,那么这条数据就不能被删除,只有当所有连接的外键数据全都被删除,这条数据才能被删除。如下图所示:id为4的数据有一个外键(id=6),只有删除了id=6的数据,才能删除id=4的数据。
    在这里插入图片描述
  • SET_NULL:设置为空,即当外键连接的那条数据被删除了,那么该数据的外键设置为空。前提是要把该数据设置为"允许为空"
  • SET_DEFAULT:设置默认值,即当外键连接的那条数据被删除了,那么该数据的外键设置为一个默认值,这个默认值只能是其他外键

拓展

自关联表

有时候我们在写评论逻辑的时候,有一级评论,一级评论下还会有二级评论,二级评论下可能还会有三级评论。这样如果做三张表显得有些夸张。这时候只需要设置一个外键,引用自身(即二级评论的外键是一级评论的主键即可,三级评论的外键是二级评论的主键)即可。

设置
# models.py
class Comment(models.Model):
	name = models.CharField(max_length=50)
	# 可以指定类名
	# comment = models.ForeignKey('Comment', on_delete=models.CASCADE, null=True)
	# 也可以直接写self,这个比较常用
	comment = models.ForeignKey('self', on_delete=models.CASCADE, null=True)
	

查询条件

我们之前已经说过了数据库的查询,现在更进一步,了解一下查询条件

查询条件加在要查询的字段后面,用双下划线 “__” 连接

  • exact和iexact(精确查询)
name = Article.objects.filter(name__exact='Jack')
name = Article.objects.filter(name__iexact='Jack')
  • contains和icontains(判断是否字段里有)
# contains大小写敏感
name = Article.objects.filter(name__contains='P')
# icontains大小写不敏感
name = Article.objects.filter(name__icontains='p')
  • in(将所有符合的数据提取出来)
id = Article.objects.filter(id__in=[1,2,3])

拓展

关联表查询
# 普通查询
articles = Article.objects.filter(name__contains='P')
author = Author.objects.filter(article__in=articles)

# 更简便的查询
author = Author.objects.filter(article__name__contains='P')

注意:Django的外键和Flask的不同,Django的外键默认会给一个反向查询(即小写的类名),而Flask需要指定backref。所以上面代码的小写article其实是Author表到Article表的一个连接。

比较运算

  • gt和gte(greater than / greater than equal)
    大于和大于等于
# 获取大于4的数据
articles = Article.objects.filter(id__gt=4)
# 获取大于等于4的数据
articles = Article.objects.filter(id__gte=4)
  • lt和lte(lighter than / lighter than equal)
    小于和小于等于
# 获取小于4的数据
articles = Article.objects.filter(id__lt=4)
# 获取小于等于4的数据
articles = Article.objects.filter(id__lte=4)
  • range(区间)

需要注意的是range(min, max)是既取min,也取max,和python里range的左闭右开不一样

# 数字范围
articles = Article.objects.filter(id__range=(1, 3))
# 时间范围
start_date = datetime(year=2020, month=12, day=1,hour=10,minute=0, second=0)
end_date = datetime(year=2021, month=5, day=1,hour=10,minute=0, second=0)
articles = Article.objects.filter(pub_time__range(start_date, end_date))
  • date:根据日期进行查询
from datetime import date
# 查询某一天的文章
article = Article.objects.filter(pub_time__date=date(year=2021, month=7, day=19))
# 如果要查询这天之前或之后的:用pub_time__date__gt或pub_time__date__lt
  • year:根据年份进行查询
# 查询某一年的文集
article = Article.objects.filter(pub_time__year=2020)
# 查询这年以前或以后的用:pub_time__year__gt或pub_time__year__lt
  • time:根据具体时间进行查询
# 查询每一天某个时间点的文章
from datetime import time
article = Article.objects.filter(pub_time__time=time(hour=10, minutes=3, second=23))

# 查询每一天某个时间范围的文章(用range)
start_time = time(hour=10, minutes=3, second=10)
end_time = time(hour=10, minutes=3, second=30)
article= Article.objects.filter(pub_time__time__range(start_time, end_time))
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值