zoukankan      html  css  js  c++  java
  • 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()
  • 相关阅读:
    背水一战 Windows 10 (90)
    背水一战 Windows 10 (89)
    背水一战 Windows 10 (88)
    背水一战 Windows 10 (87)
    背水一战 Windows 10 (86)
    背水一战 Windows 10 (85)
    背水一战 Windows 10 (84)
    背水一战 Windows 10 (83)
    背水一战 Windows 10 (82)
    背水一战 Windows 10 (81)
  • 原文地址:https://www.cnblogs.com/randomlee/p/12112167.html
Copyright © 2011-2022 走看看