Django Form ModelMultipleChoiceField将数据保存到数据库的问题

gab6jxml  于 2023-05-01  发布在  Go
关注(0)|答案(1)|浏览(116)

我正在创建我的第一个Django应用程序。它是一个图书馆管理系统。我有三个模型:

class Authors(models.Model):
    firstName = models.CharField(max_length=20)
    lastName = models.CharField(max_length=20)
    
    def __str__(self):
        return f"{self.firstName.title()} {self.lastName.title()}"
    
    def save(self):
        self.firstName = self.firstName.casefold()
        self.lastName = self.lastName.casefold()
        super().save()
    
class Books(models.Model):
    isbn = models.BigIntegerField(primary_key=True, validators=[
        MinValueValidator(9780000000000),
        MaxValueValidator(9799999999999),
    ])
    bookName = models.CharField(max_length=50)
    authors = models.ManyToManyField(Authors, through='BookAuth')
    pubName = models.CharField(max_length=20)
    inventory = models.IntegerField(default=0)
    
    def __str__(self):
        return f"{self.pk} || {self.getName()}"
    
    def getName(self):
        name, bname = self.bookName.split(), ""
        for x in name:
            bname += x[0].upper() + x[1:] + " "
        return bname[:-1]
    
    def getAuthors(self):
        bookAuths = BookAuth.objects.filter(isbn=self.isbn)
        auth = ""
        for bookAuth in bookAuths:
            auth += f"{bookAuth.getAuth()}, "
        return auth[:-2]
    
    def save(self):
        self.bookName = self.bookName.casefold()
        self.pubName = self.pubName.casefold()
        super().save()

class BookAuth(models.Model):
    isbn = models.ForeignKey(Books, on_delete=models.CASCADE)
    auth = models.ForeignKey(Authors, on_delete=models.CASCADE)
    
    def getAuth(self):
        return Authors.objects.get(id=self.auth.id)
    
    def __str__(self):
        return f"{self.auth} - {self.isbn}"

在这里,我将书籍和作者分开存储,并使用BookAuth模型来建立ManyToMany关系。我在添加一本新书时遇到了问题。为此,我有两个表单,一个是添加新作者,另一个是添加新书。Thewww.example. www.example.com 文件看起来像这样:

class AddAuthors(forms.ModelForm):
    class Meta:
        model = Authors
        fields = ("__all__")

class AddBooks(forms.ModelForm):
    author = forms.ModelMultipleChoiceField(
        queryset=Authors.objects.all(),
        widget=CheckboxSelectMultiple,
        )
    class Meta:
        model = Books
        fields = ('isbn', 'bookName', 'authors', 'pubName', 'inventory')

我想有一个多项选择字段的作者属性,添加一个或多个作者到一本新书。我正在使用以下视图处理此表单:

def books(request):
    if request.method == "GET":
        cont1 = footer_counter() # returns a dictionary with total no of members, books and total inventory
        cont2 = {'bookform': AddBooks(), 'authform': AddAuthors(), 'books': Books.objects.all()}
        return render(request, 'books.html', {**cont1,**cont2})
    if request.method == "POST":
        authData = AddAuthors(request.POST)
        bookData = AddBooks(request.POST)
        if authData.is_valid():
            authData.save()
        elif bookData.is_valid():
            bookData.save()
        return redirect(books)

但我这里的问题是,在我提交表单之后,没有任何数据被保存到模型(Book或BookAuth)中。Django给出了以下日志消息:[27/Apr/2023 14:13:03] "POST /books/ HTTP/1.1" 302 0[27/Apr/2023 14:13:03] "GET /books/ HTTP/1.1" 200 8009
我该怎么解决这个问题?谢谢大家。
附加:表单的Django模板语言:

<div class="col-md-6 text-center">
  <form method="post" autocomplete="off">
  {% csrf_token %}
    <table class="table text-center">
      <thead class="table-dark">
        <tr><th colspan="2">Add a new Book</th></tr>
      </thead>
      <tbody>
        <tr>
          <td class="col-4"><label for="{{ bookform.isbn.id_for_label }}" class="form-label text-white">ISBN</label></td>
          <td class="col-8">{{ bookform.isbn }}</td>
        </tr>
        <tr>
          <td><label for="{{ bookform.bookName.id_for_label }}" class="form-label text-white">Book Name</label></td>
          <td>{{ bookform.bookName }}</td>
        </tr>
        <tr>
          <td><label for="{{ bookform.author.id_for_label }}" class="form-label text-white control-label">Authors</label>
          </td>
          <td>{{ bookform.author }}</td>
        </tr>
        <tr>
          <td><label for="{{ bookform.pubName.id_for_label }}" class="form-label text-white">Publisher Name</label></td>
          <td>{{ bookform.pubName }}</td>
        </tr>
        <tr>
          <td><label for="{{ bookform.inventory.id_for_label }}" class="form-label text-white">Inventory</label></td>
          <td>{{ bookform.inventory }}</td>
        </tr>
      </tbody>
    </table>
    <button type="submit" class="btn btn-primary mx-auto">Add Book</button>
  </form>
</div>

提交后,数据未保存到数据库。它按照预期的方式工作,但不将数据保存到模型中。(我检查了使用flag变量和print语句,以及www.example www.example.com _valid()返回false,即使我输入了正确的值)

f1tvaqid

f1tvaqid1#

您的问题来自表单中字段的名称。
表单中的字段称为author,但在字段中您获得authors(来自模型)。
只需像这样编辑您的表单:

class AddBooks(forms.ModelForm):
authors = forms.ModelMultipleChoiceField(
    queryset=Authors.objects.all(),
    widget=CheckboxSelectMultiple,
    )
class Meta:
    model = Books
    fields = ('isbn', 'bookName', 'authors', 'pubName', 'inventory')

而且应该能成功

相关问题