Django完整性错误_id可能不为null,ForeignKey id赋值

时间:2014-05-29 18:42:28

标签: python django

我在理解Django(v1.6.5)在保存时将id分配给不同对象的方式时遇到了问题。以最小的例子:

#models.py

class Book(models.Model):
    title = models.CharField(max_length=10)

class Page(models.Model):
    number = models.SmallIntegerField()
    book   = models.ForeignKey(Book)

以下视图在保存my_page时抛出“IntegrityError,book_id可能不为NULL”,但是我倾向于说book_id确实存在,因为在该阶段已经为该书调用了save()。

#view.py

my_book = Book(title="My book")

#solution1 : having my_book.save() here

my_page = Page(number = 1, book = my_book)
my_book.save()
print("book id",my_page.book.id) #book.id does exist at that point!

#solution2: my_page.book = my_book

my_page.save()   #throws the IntegrityError exception

有一些简单的解决方案可以使代码在上面工作,但我想知道第一种方法有什么问题。我是否遗漏了某些东西,或者Django处理ForeignKeys的方式是一个小故障/限制?

3 个答案:

答案 0 :(得分:3)

您应该在设置my_page.book = book之前保存图书。

ticket 10811描述了您遇到的行为。

答案 1 :(得分:1)

我明白你的观点,但目前的行为似乎更明确。 my_book只是一个Python对象,其所有属性(包括id)都可以更改。因此,假设用户想要在实例化时存在的值似乎更安全。

例如,Django idiom for copying a database row涉及重用同一个对象来表示多个模型实例。在你的情况下可能看起来像:

my_book = Book(title="My book")
my_page = Page(number=1, book=my_book)
my_book.save()

my_book.id = None
my_book.save()  # copy the book to a new row with a new id

my_page.save()

那么my_page应指向哪本书?我认为开发人员要求你在这里明确是正确的。 the associated ticket的解决方案将更加直接,因为如果ValueError尚未保存,则在尝试实例化my_page时会获得my_book

答案 2 :(得分:0)

如果模型中有foreign key,那么您需要提供整个object以便在其中存储记录。例如,如果您想在Page model中保存带有图书的数字,那么您需要提供book foreign key a book object,因为它不是正常字段,而是foreign key to the book model.  它可以像下面那样完成

  

my_page = Page(title="my title", book=Book.objects.get(pk=id))

所以得出结论,你不能简单地通过给外键提供字符串来插入记录,你必须给出object to which foreign key is pointing。希望有所帮助