前提:
如果你用的是php_study,你需要在设置的mysql的配置文件里更改默认的数据库引擎,设置为InnoDB,InnoDB支持数据库的外键约束。
通过models.ForeignKey来设置外键,他有两个必须要传的参数
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,即级联删除。也就是说如果外键对应的数据被删除了,那么这条数据也会被删除。
下面列举了一些其他的比较常用的删除操作:
有时候我们在写评论逻辑的时候,有一级评论,一级评论下还会有二级评论,二级评论下可能还会有三级评论。这样如果做三张表显得有些夸张。这时候只需要设置一个外键,引用自身(即二级评论的外键是一级评论的主键即可,三级评论的外键是二级评论的主键)即可。
# 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)
我们之前已经说过了数据库的查询,现在更进一步,了解一下查询条件
查询条件加在要查询的字段后面,用双下划线 “__” 连接。
name = Article.objects.filter(name__exact='Jack')
name = Article.objects.filter(name__iexact='Jack')
# contains大小写敏感
name = Article.objects.filter(name__contains='P')
# icontains大小写不敏感
name = Article.objects.filter(name__icontains='p')
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表的一个连接。
# 获取大于4的数据
articles = Article.objects.filter(id__gt=4)
# 获取大于等于4的数据
articles = Article.objects.filter(id__gte=4)
# 获取小于4的数据
articles = Article.objects.filter(id__lt=4)
# 获取小于等于4的数据
articles = Article.objects.filter(id__lte=4)
需要注意的是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))
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
# 查询某一年的文集
article = Article.objects.filter(pub_time__year=2020)
# 查询这年以前或以后的用:pub_time__year__gt或pub_time__year__lt
# 查询每一天某个时间点的文章
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))