ValueError: variable needs to have a value for field "id" before this many to many relationship can be used - Django

ValueError: variable needs to have a value for field "id" before this many to many relationship can be used - Django

我在 Django 中创建了一个数据模型,现在我创建了一个脚本来使用 web-scraped 值自动填充模型。但是,当我 运行 脚本时,出现以下错误: ValueError: 变量需要有字段 "id" 的值才能使用这种多对多关系

Models.py

class Books(models.Model):
    title = models.CharField(max_length=100)

    def __str__(self):
        return self.title

    class Meta:
        ordering = ['-title']

class Author(models.Model):
    book = models.ManyToManyField(Books)
    first_name = models.CharField(max_length=150)
    last_name = models.CharField(max_length=200)

    def __str__(self):
        return "{} {}".format(self.first_name, self.last_name)

    class Meta:
        ordering = ['last_name','first_name']


class Book_details(models.Model):
    book = models.ForeignKey(Books, 
                            on_delete=models.CASCADE, 
                            null=True) # models.SET_NULL weggehaald
    pages = models.CharField(max_length=250)
    publ_year = models.CharField(max_length=250)
    edition = models.CharField(max_length=30) # paperback, hardcover, audiobook, etc


    def __str__(self):
        return "{} - pages: <{}>, edition: <{}>".format(self.book.title, 
                                                    self.pages, 
                                                    self.edition)# 

class Cover(models.Model):
    book = models.OneToOneField(Books, 
                            on_delete=models.CASCADE)
    path = models.CharField(max_length=500)

    def __str__(self):
        return "<Cover <path={}>".format(self.id, self.path)

populate_script

def add_book(title):
    b = Books.objects.get_or_create(title = title)[0]
    print(b)
    b.save()
    return b

def populate(scraped_tuple):
    fake = Faker()

    for _ in range(len(scraped_tuple)):

        b_title = scraped_tuple[_][0][0]
        new_book = add_book(b_title)

        b_author_first = scraped_tuple[_][0][1].split(" ")[0]
        b_author_last = scraped_tuple[_][0][1].split(" ")[1]
        b_pages = scraped_tuple[_][0][2].split(" ")[0]
        b_publ_year = fake.year()
        b_edition = scraped_tuple[_][0][3].split(",")[0]
        b_cover = scraped_tuple[_][0][4]

        new_details = Book_details.objects.get_or_create(book = new_book, pages = b_pages, publ_year = b_publ_year, edition = b_edition)[0]

        new_author = Author.objects.get_or_create(book = new_book, first_name = b_author_first, last_name = b_author_last)[0]

        new_cover = Cover.objects.get_or_create(book = new_book, path = b_cover)[0]

scraped_tuple 是来自包含详细信息的网络抓取工具的 return 值。

(部分)回溯:

Books.models.DoesNotExist: Author matching query does not exist.
  File "C:\path\to\LibraryApp\Library_WebA
pp\Library\populate.py", line 45, in populate
    new_author = Author.objects.get_or_create(book = new_book, first_name = b_author_first, last_nam
e = b_author_last)[0]

其次是:

ValueError: "<Author: Mary McCarthy>" needs to have a value for field "id" before this many-to-many relationship can be used.

因此,由于 Author 模型中的 many-to-many 字段 "book",在尝试执行 new_author 语句时似乎出现了严重错误。我该如何解决这个问题。我是否需要像 add_book() 中的书籍那样为作者 object 提供类似的功能? new_details 语句似乎执行得很好(标题和 book_details 正确显示在 Django 管理部分的数据库中)。

docs 中所述,用户 .add() 用于关联多对多字段中的记录。

def populate(scraped_tuple):
fake = Faker()

for _ in range(len(scraped_tuple)):

    b_title = scraped_tuple[_][0][0]
    new_book = add_book(b_title)

    b_author_first = scraped_tuple[_][0][1].split(" ")[0]
    b_author_last = scraped_tuple[_][0][1].split(" ")[1]
    b_pages = scraped_tuple[_][0][2].split(" ")[0]
    b_publ_year = fake.year()
    b_edition = scraped_tuple[_][0][3].split(",")[0]
    b_cover = scraped_tuple[_][0][4]

    new_details = Book_details.objects.get_or_create(book = new_book, pages = b_pages, publ_year = b_publ_year, edition = b_edition)[0]

    new_author = Author.objects.get_or_create(first_name = b_author_first, last_name = b_author_last)[0]

    # add many to many fields this way:
    new_author.book.add(new_book)

    new_cover = Cover.objects.get_or_create(book = new_book, path = b_cover)[0]