在写项目的过程中我们不可避免的会使用到外键这个东西,那么Django中是怎样来使用外键的呢?

了解外键

在MySQL中,表有两种引擎,一种是InnoDB,另外一种是myisam。如果使用的是InnoDB引擎,是支持外键约束的。外键的存在使得ORM框架在处理表关系的时候异常的强大。MySQL数据库默认使用的也是InnoDB引擎。

使用外键

新建一个项目,创建一个article的app,添加至settings中,并且在settings中设置数据库的连接,调至整个项目能运行为止。

类定义为class ForeignKey(to,on_delete,**options)。第一个参数是引用的是哪个模型,第二个参数是在使用外键引用的模型数据被删除了,这个字段该如何处理,比如有CASCADE、SET_NULL等(外键删除各个参数的意思)。这里以一个实际案例来说明。比如有一个Category和一个Article两个模型。一个种类下可以包含多篇文章,一个Article只能有一个种类,并且通过外键进行引用。那么相关的示例代码如下:

在同一个app中使用外键

在article中的models中写入代码:

from django.db import models

# Create your models here.
class Category(models.Model):
    name = models.CharField(max_length=100)

class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    # 是由Category影响Article
    category = models.ForeignKey('Category',on_delete=models.CASCADE)

这里我们就在Article中设置了一个外键category。

以上使用ForeignKey来定义模型之间的关系。即在article的实例中可以通过category属性来操作对应的Category模型。这样使用起来非常的方便。示例代码如下:views中写入

from django.shortcuts import render
from . import models
from django.http import HttpResponse

# Create your views here.
def index(request):
    
    # 插入数据
    # article = models.Article(title='abc',content='111')
    # category = models.Category(name='最新文章')
    # category.save()
    # article.category = category
    # article.save()

    #读取数据
    article = models.Article.objects.first()
    print(article.category.name)
    return HttpResponse('successful')

在上面代码中把相应的注释去了,就能够进行测试了。

为什么使用了ForeignKey后,就能通过category访问到对应的Catrgory对象呢。因此在底层,Django为Article表添加了一个属性名_id的字段(比如category的字段名称是category_id),这个字段是一个外键,记录着对应的种类的主键。以后通过article.category访问的时候,实际上是先通过category_id找到对应的数据,然后再提取Category表中的这条数据,形成一个模型。

如果想要引用另外一个app的模型,那么应该在传递to参数的时候,使用app.model_name进行指定。例如,如果User和Article不是在同一个app中,那么在引用的时候的示例代码如下:
首先新建一个user的app,并且添加至settings中,在user中的models中写入代码,创建一个User模型

from django.db import models

# Create your models here.
class User(models.Model):
    username = models.CharField(max_length=100)

再在article中的models中添加这个外键,即在Article这个模型中新添加一个属性

# 将user中的User这个模型作为外键
author = models.ForeignKey('user.User',on_delete=models.CASCADE,null=True)

如果模型的外键引用的是本身自己这个模型,那么to参数可以为self,或者是这个模型的名字。在论坛开发中,一般评论都可以进行二级评论,即可以针对另外一个评论进行评论,那么在定义模型的时候就需要使用外键来引用自身。示例代码如下:

class Comment(models.Model):
    content = models.TextField()
    orihin_comment = models.ForeignKey('self',on_delete=models.CASCADE)

这样我们就实现了添加了一个外键引用自身。

外间删除操作的参数意思:

如果一个模型使用了外键。那么在对方那个模型被删掉后,该进行什么样的操作。可以通过on_delete来指定。可以指定的类型如下:

  • CASCADE:级联操作。如果外键对应的那条数据被删除了,那么这条数据也会被删除。
  • PROTECT:受保护。即只要这条数据引用了外键的那条数据,那么就不能删除外键的那条数据。如果我们强行删除,Django就会报错。
  • SET_NULL:设置为空。如果外键的那条数据被删除了,那么在本条数据上就将这个字段设置为空。如果设置这个选项,前提是要指定这个字段可以为空。
  • SET_DEFAULT:设置默认值。如果外键的那条数据被删除了,那么本条数据上就将这个字段设置为默认值。如果设置这个选项,== 前提是要指定这个字段一个默认值 ==。
  • SET():如果外键的那条数据被删除了。那么将会获取SET函数中的值来作为这个外键的值。SET函数可以接收一个可以调用的对象(比如函数或者方法),如果是可以调用的对象,那么会将这个对象调用后的结果作为值返回回去。== 可以不用指定默认值 ==
  • DO_NOTHING:不采取任何行为。一切全看数据库级别的约束。

以上这些选项只是Django级别的,数据级别依旧是RESTRICT!

数据库层面的约束有四种:

  • RESTRICT:默认的选项,如果想要删除父表的记录时,而在子表中有关联该父表的记录,则不允许删除父表中的记录;
  • NOACTION:同 RESTRICT效果一样,也是首先先检查外键;
  • CASCADE:父表delete、update的时候,子表会delete、update掉关联记录;
  • SET NULL:父表delete、update的时候,子表会将关联记录的外键字段所在列设为null,所以注意在设计子表时外键不能设为not null;

参考链接:https://www.jb51.net/article/257166.htm

为什么ORM能越过数据库的约束呢?

是因为ORM操作是反过来的,比如我们在ORM模型中设置了on_delete=models.CASCADE,那么在进行删除的时候,如果发现在数据库层面有父表约束着它,使他不能被删除,那么ORM就会先去删除父表,再来删除指定的表,从而达到越过了数据库层面的约束。

到此这篇关于Django中外键使用总结的文章就介绍到这了,更多相关Django 外键内容请搜索Devmax以前的文章或继续浏览下面的相关文章希望大家以后多多支持Devmax!

Django中外键使用总结的更多相关文章

  1. 难以在Android和iPhone上部署Django应用程序..计划切换到PHP而不是Django

    .我是否需要学习PHP,C,Java或其他任何东西,或者只要知道django和python就可以做到这一点?

  2. Android发送发送请求到django服务器csrf失败

    我想我的Android应用程序能够发送一些信息到我的django服务器.所以我做的Android应用程序发送一个发布请求到mysite/上传页面,django的这个页面的视图将基于post数据工作.问题是服务器对post请求的响应,关于csrf验证失败.看看这个问题,似乎我可能必须先从服务器获取一个csrf令牌,然后用该令牌做帖子但是我不知道我该怎么做.编辑:我已经发现,我可以使用视图装饰器@cs

  3. android – greenDAO不会在表中生成FOREIGN KEY(…)约束

    当我创建如下所示的双向1:n关系时,生成器不会在表上使用任何FOREIGNKEY(…)约束.这是正常吗?是否应该在表中生成FOREIGNKEY(…)约束,还是仅在运行时通过代码强制执行?

  4. pycharm社区版安装django并创建一个简单项目的全过程

    社区版的pycharm跟专业版的pycharm应用差别还是不太大,下面这篇文章主要给大家介绍了关于pycharm社区版安装django并创建一个简单项目的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

  5. Django 报错:Broken pipe from ('127.0.0.1', 58924)的解决

    这篇文章主要介绍了Django 报错:Broken pipe from ('127.0.0.1', 58924)的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  6. 解决Django cors跨域问题

    这篇文章主要介绍了解决Django cors跨域问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  7. 虚拟环境下搭建一个Django项目

    这篇文章主要为大家介绍了虚拟环境下搭建一个Django项目的实现过程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  8. Django ORM F对象和Q对象查询

    Django提供了两个非常有用的工具:F对象和Q对象,方便了在一些特殊场景下的查询过程,这篇文章主要介绍了Django ORM F对象和Q对象查询,需要的朋友可以参考下

  9. Python Django教程之实现新闻应用程序

    Django是一个用Python编写的高级框架,它允许我们创建服务器端Web应用程序。在本文中,我们将了解如何使用Django创建新闻应用程序,感兴趣的可以尝试一下

  10. django安装xadmin及问题解决

    本文主要介绍了django安装xadmin及问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

随机推荐

  1. 10 个Python中Pip的使用技巧分享

    众所周知,pip 可以安装、更新、卸载 Python 的第三方库,非常方便。本文小编为大家总结了Python中Pip的使用技巧,需要的可以参考一下

  2. python数学建模之三大模型与十大常用算法详情

    这篇文章主要介绍了python数学建模之三大模型与十大常用算法详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感想取得小伙伴可以参考一下

  3. Python爬取奶茶店数据分析哪家最好喝以及性价比

    这篇文章主要介绍了用Python告诉你奶茶哪家最好喝性价比最高,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  4. 使用pyinstaller打包.exe文件的详细教程

    PyInstaller是一个跨平台的Python应用打包工具,能够把 Python 脚本及其所在的 Python 解释器打包成可执行文件,下面这篇文章主要给大家介绍了关于使用pyinstaller打包.exe文件的相关资料,需要的朋友可以参考下

  5. 基于Python实现射击小游戏的制作

    这篇文章主要介绍了如何利用Python制作一个自己专属的第一人称射击小游戏,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起动手试一试

  6. Python list append方法之给列表追加元素

    这篇文章主要介绍了Python list append方法如何给列表追加元素,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  7. Pytest+Request+Allure+Jenkins实现接口自动化

    这篇文章介绍了Pytest+Request+Allure+Jenkins实现接口自动化的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  8. 利用python实现简单的情感分析实例教程

    商品评论挖掘、电影推荐、股市预测……情感分析大有用武之地,下面这篇文章主要给大家介绍了关于利用python实现简单的情感分析的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下

  9. 利用Python上传日志并监控告警的方法详解

    这篇文章将详细为大家介绍如何通过阿里云日志服务搭建一套通过Python上传日志、配置日志告警的监控服务,感兴趣的小伙伴可以了解一下

  10. Pycharm中运行程序在Python console中执行,不是直接Run问题

    这篇文章主要介绍了Pycharm中运行程序在Python console中执行,不是直接Run问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

返回
顶部