前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Django官方文档小结(一) -- Models模型

Django官方文档小结(一) -- Models模型

作者头像
Autooooooo
发布2020-11-09 10:02:30
7590
发布2020-11-09 10:02:30
举报
文章被收录于专栏:Coxhuang

Django 关系字段

本文主要内容是关于Django框架中models的知识小结

#1 环境

代码语言:javascript
复制
Python3.7.3
Django==2.0.7

#2 字段

#2.1 一对多(ForeignKey)

一对多 : fk字段在"多"的models中定义

代码语言:javascript
复制
from django.db import models

class Blog(models.Model):
    name = models.CharField(max_length=100)
    tagline = models.TextField()

    def __str__(self):
        return self.name

class Author(models.Model):
    name = models.CharField(max_length=200)
    email = models.EmailField()

    def __str__(self):
        return self.name

class Entry(models.Model):
    blog = models.ForeignKey(
        Blog,
        on_delete=models.CASCADE,
        related_name="entryblogs",
        related_query_name="entryqueryblogs"
    )
    headline = models.CharField(max_length=255)
    body_text = models.TextField()
    pub_date = models.DateField()
    mod_date = models.DateField()
    authors = models.ManyToManyField(Author)
    n_comments = models.IntegerField()
    n_pingbacks = models.IntegerField()
    rating = models.IntegerField()

    def __str__(self):
        return self.headline
#2.1 参数
代码语言:javascript
复制
models.ForeignKey(to,on_delete,** options)
# to : 关联的类(必填)
# on_delete : 与"关联表"的关系(必填)
#2.2 自关联
代码语言:javascript
复制
models.ForeignKey(to='self', on_delete=models.CASCADE)
#2.3 关联关系
代码语言:javascript
复制
on_delete=None,               # 删除关联表中的数据时,当前表与其关联的field的行为
on_delete=models.CASCADE,     # 删除关联数据,与之关联也删除
on_delete=models.DO_NOTHING,  # 删除关联数据,什么也不做
on_delete=models.PROTECT,     # 删除关联数据,引发错误ProtectedError
# models.ForeignKey('关联表', on_delete=models.SET_NULL, blank=True, null=True)
on_delete=models.SET_NULL,    # 删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空,一对一同理)
# models.ForeignKey('关联表', on_delete=models.SET_DEFAULT, default='默认值')
on_delete=models.SET_DEFAULT, # 删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值,一对一同理)
on_delete=models.SET,         # 删除关联数据,
a. 与之关联的值设置为指定值,设置:models.SET(值)
b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)
#2.4 数据库表示

在生成数据库时,Django追加"_id"字段名称来创建其数据库列名,可以通过指定显式更改此内容db_column

#2.5 反向查找 (related_name)
代码语言:javascript
复制
from django.db import models

class Blog(models.Model):
    name = models.CharField(max_length=100)
    # ...
    
class Entry(models.Model):
    blog = models.ForeignKey(
        Blog,
        on_delete=models.CASCADE,
        related_name="entryblogs",
    )
    # ...
  • 正向查找 (Entry->Blog)

由存放外键的表(Entry)->查->被关联的表(Blog)

代码语言:javascript
复制
>>> e = models.Entry.objects.get(id=1)
>>> e.blog
<Blog: haha>
  • 反向查找 (Blog->Entry)

由被关联的表(Blog)->查->存放外键的表(Entry)

代码语言:javascript
复制
>>> b = models.Blog.objects.get(id=1)
>>> b.entryblogs
<django.db.models.fields.related_descriptors.create_reverse_many_to_one_manager.<locals>.RelatedManager object at 0x10d58c908>
>>> b.entryblogs.all() # 一对多,所以反向获取到的数据是一个多条数据,需要all()
<QuerySet [<Entry: 1>]>
#2.6 反向直接获取数据 (related_query_name)
  • 正常查询
代码语言:javascript
复制
>>> b = models.Blog.objects.get(id=1)
>>> models.Entry.objects.filter(blog=b).filter(headline=1)
<QuerySet [<Entry: 1>]>
  • 使用反向获取数据
代码语言:javascript
复制
>>> models.Blog.objects.filter(id=1).filter(entryqueryblogs__headline=1)
<QuerySet [<Blog: haha>]>

#2.2 多对多 (ManyToManyField)

ManyToManyField(to,**options)

MtoM字段根据需求可以放到两个有关联的表中的任意一个

代码语言:javascript
复制
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=200)
    email = models.EmailField()
    # ...

class Entry(models.Model):
    authors = models.ManyToManyField(Author)
    # ...

#2.3 一对一 (OneToOneField)

代码语言:javascript
复制
OneToOneField(to,on_delete,parent_link = False,** options)

#3 Meta

代码语言:javascript
复制
class Entry(models.Model):
    blog = models.ForeignKey(
        Blog,
        on_delete=models.CASCADE,
        related_name="entryblogs",
        related_query_name="entryqueryblogs"
    )
    # ...

    class Meta:
        pass

#3.1 设置表名

代码语言:javascript
复制
class Entry(models.Model):
    blog = models.ForeignKey(
        Blog,
        on_delete=models.CASCADE,
        related_name="entryblogs",
        related_query_name="entryqueryblogs"
    )

    class Meta:
        db_table = "app名_Entry" 
        # app名+类名(个人喜好,根据项目中遇到的坑,我建议表名应该为:小写app名+小写的类名)

#3.2 跨表订购 (order_with_respect_to)

目前通过做过的这些项目,这个功能感觉有点鸡肋,具体怎么用还是要说一下

  1. 格式
代码语言:javascript
复制
class Entry(models.Model):
    blog = models.ForeignKey(
        Blog,
        on_delete=models.CASCADE,
        related_name="entryblogs",
        related_query_name="entryqueryblogs"
    )
    # ...

    class Meta:
        order_with_respect_to = 'blog' # fk字段名
  1. 使用场景
代码语言:javascript
复制
>>> b = models.Blog.objects.get(id=1)
>>> b
<Blog: haha>
>>> b.get_entry_order()
<QuerySet [1, 2]> # 里面存放的仅仅是int类型的数据,并不是obj

拿到的仅仅是一个由id组成的列表,并不是我们想要的queryset数据

  1. 使用
代码语言:javascript
复制
# 拿到被关联的obj数据
b = models.Blog.objects.get(id=1) 
# obj.get_小写关联的表名_order()
b.get_entry_order()

#3.3 联合唯一 (unique_together)

给定的字段,加起来在表中保持唯一值

代码语言:javascript
复制
class Entry(models.Model):
    body_text = models.TextField()
    pub_date = models.DateField()
    # ...
    
    class Meta:
        unique_together = (("body_text", "pub_date"),)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/05/26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Django 关系字段
  • #1 环境
  • #2 字段
    • #2.1 一对多(ForeignKey)
      • #2.1 参数
      • #2.2 自关联
      • #2.3 关联关系
      • #2.4 数据库表示
      • #2.5 反向查找 (related_name)
      • #2.6 反向直接获取数据 (related_query_name)
    • #2.2 多对多 (ManyToManyField)
      • #2.3 一对一 (OneToOneField)
      • #3 Meta
        • #3.1 设置表名
          • #3.2 跨表订购 (order_with_respect_to)
            • #3.3 联合唯一 (unique_together)
            相关产品与服务
            数据库
            云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档