• Django 官方文档中对于关联表的关联对象的操作 https://docs.djangoproject.com/zh-hans/3.0/topics/db/queries/#related-objects


    关联对象

    当你在模型中定义了关联关系(如 ForeignKey, OneToOneField, 或 ManyToManyField),该模型的实例将会自动获取一套 API,能快捷地访问关联对象。

    拿本文开始的模型做例子,一个 Entry 对象 e 通过 blog 属性获取其关联的 Blog 对象: e.blog

    (在幕后,这个函数是由 Python descriptors 实现的。这玩意一般不会麻烦你,但是我们为你指出了注意点。)

    Django 也提供了从关联关系 另一边 访问的 API —— 从被关联模型到定义关联关系的模型的连接。例如,一个 Blog 对象 b 能通过 entry_set 属性 b.entry_set.all() 访问包含所有关联 Entry 对象的列表。

    本章节中的所有例子都是用了本页开头定义的 Blog, Author 和 Entry 模型。

    一对多关联

    正向访问

    If a model has a ForeignKey, instances of that model will have access to the related (foreign) object via an attribute of the model.

    举例:

    >>> e = Entry.objects.get(id=2)
    >>> e.blog # Returns the related Blog object.
    

    你可以通过 foreign-key 属性获取和设置值。如你所想,对外键的修改直到你调用 save() 后才会被存入数据库。例子:

    >>> e = Entry.objects.get(id=2)
    >>> e.blog = some_blog
    >>> e.save()
    

    若 ForeignKey 字段配置了 null=True (即其允许 NULL 值),你可以指定值为 None 移除关联。例子:

    >>> e = Entry.objects.get(id=2)
    >>> e.blog = None
    >>> e.save() # "UPDATE blog_entry SET blog_id = NULL ...;"
    

    首次通过正向一对多关联访问关联对象时会缓存关联关系。后续在同一对象上通过外键的访问也会被缓存。例子:

    >>> e = Entry.objects.get(id=2)
    >>> print(e.blog)  # Hits the database to retrieve the associated Blog.
    >>> print(e.blog)  # Doesn't hit the database; uses cached version.
    

    注意 select_related() QuerySet 方法会预先用所有一对多关联对象填充缓存。例子:

    >>> e = Entry.objects.select_related().get(id=2)
    >>> print(e.blog)  # Doesn't hit the database; uses cached version.
    >>> print(e.blog)  # Doesn't hit the database; uses cached version.
    

    “反向” 关联

    若模型有 ForeignKey,外键关联的模型实例将能访问 Manager,后者会返回第一个模型的所有实例。默认情况下,该 Manager 名为 FOO_set, FOO 即源模型名的小写形式。 Manager 返回 QuerySets,后者能以 “检索对象” 章节介绍的方式进行筛选和操作。

    举例:

    >>> b = Blog.objects.get(id=1)
    >>> b.entry_set.all() # Returns all Entry objects related to Blog.
    
    # b.entry_set is a Manager that returns QuerySets.
    >>> b.entry_set.filter(headline__contains='Lennon')
    >>> b.entry_set.count()
    

    你可以在定义 ForeignKey 时设置 related_name 参数重写这个 FOO_set 名。例如,若修改 Entry 模型为 blog =ForeignKey(Blog, on_delete=models.CASCADE, related_name='entries'),前文示例代码会看起来像这样:

    >>> b = Blog.objects.get(id=1)
    >>> b.entries.all() # Returns all Entry objects related to Blog.
    
    # b.entries is a Manager that returns QuerySets.
    >>> b.entries.filter(headline__contains='Lennon')
    >>> b.entries.count()
    

    使用自定义反向管理器

    RelatedManager 反向关联的默认实现是该模型 默认管理器 一个实例。若你想为某个查询指定一个不同的管理器,可以使用如下语法:

    from django.db import models
    
    class Entry(models.Model):
        #...
        objects = models.Manager()  # Default Manager
        entries = EntryManager()    # Custom Manager
    
    b = Blog.objects.get(id=1)
    b.entry_set(manager='entries').all()
    

    若 EntryManager 在其 get_queryset() 方法执行了默认过滤行为,改行为会应用到 all() 调用中。

    当然,指定一个自定义反向管理也允许你调用模型自定义方法:

    b.entry_set(manager='entries').is_published()
  • 相关阅读:
    PHP获取当前页面完整url地址,包括参数的函数
    研究在SAE上搭建最新wordpress
    CentOS6.5 编译安装lnmp环境
    cried me a river--kristinia debarge
    Bad Day -- Daniel Powter
    Back to December -- Taylor Swift
    英语单词的偏旁部首之常见前缀(一)
    21 Guns -- Green Day
    影子
    BNUOJ 1037 精神控制
  • 原文地址:https://www.cnblogs.com/randomlee/p/12112167.html
Copyright © 2020-2023  润新知