【问题标题】:Django: How to avoid reassigning ForeignKey on every save?Django:如何避免在每次保存时重新分配 ForeignKey?
【发布时间】:2013-01-05 16:35:13
【问题描述】:

我想保存A 对象和B 对象。 A 有一个指向 B 的外键。 B 有一个到 A 的 OneToOneField。有没有办法让我不必在每次保存之间重新分配变量?还是有更好的方法?

# The models a and b were created earlier in code
# a.b = b  Was already set earlier in code
# b.a = a  Was already set earlier in code
with transaction.commit_on_success():
    a.save() # pk created for a
    b.a = a  # attach a.pk to b
    b.save() # pk created for b
    a.b = b  # attach b.pk to a
    a.save() # re-save a to database

【问题讨论】:

    标签: django django-database


    【解决方案1】:

    “A 有一个到 B 的外键。B 有一个到 A 的 OneToOneField。”我不认为这是建立你们关系的方式。您可以将 B 设置为 A 的 ForeignKey,然后您可以使用 B.a_set.all() 从 B 访问 A。

    套用here 的解释,使用以下模型定义,Book 与 Publisher 是一对多(外键),与 Author 是多对多。 (~~~~只是表示与模型之间的关系无关的其他东西)

    class Publisher(~~~~):
        ~~~~
    
    class Author(~~~~):
        ~~~~
    
    class Book(~~~~):
        publisher = models.ForeignKey(Publisher)
        authors = models.ManyToManyField(Author)
    

    然后您可以像这样访问给定书籍的出版商和作者:

    b = Book.objects.get(id=50)
    publisher1 = b.publisher # publisher object for a given book
    author_set = b.authors.all() # query set of authors for a given book
    

    你可以做相反的关系(在上面的模型中没有明确定义)。

    p = Publisher.objects.get(name='Apress Publishing')
    p.book_set.all() # query set of books for a given publisher
    publisher1.book_set.all() # set of books for the publisher from above.
    a = Author.objects.get(name="JK Rowling")
    a.book_set.all() # query set of books for a given author
    

    每当您更新对象字段时,您都需要调用save() 将其保存在数据库中,但在此之前您不需要重新分配 ForeignKey 或任何其他字段。如果这对您不起作用,也许是因为模型之间的时髦关系。我不是 100% 确定,但我认为对象获得(新)主键的唯一时间是它第一次保存到数据库中,然后是它的第一次 pk。

    【讨论】:

    • 您是正确的,pk 仅在第一次保存模型时创建(不幸的是,这并不意味着需要更少的编码:()。我有一个 OneToOneField 的原因是很容易跟踪最后创建的 A 模型。如果我没有那个 OneToOneField,那么我必须使用 B 的反向访问,这需要每次都进行数据库搜索。浪费计算和数据库访问。b.a.order_by('created')[-1]
    猜你喜欢
    • 2015-02-15
    • 2014-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    相关资源
    最近更新 更多