我正在构建一个非常基本的应用程序(我的第一个Django应用程序)。我希望用户在数据库中添加一本书。所以,我有一个模型可以添加一本书,以及它的名称和图像(书籍封面)。
这很好用。现在,我想上传本书的章节,一章将有多个页面,因此有多个文件(比如.pdf文件)。我为章节创建了另一个类,并通过ForeginKey链接了这个类。
我在SO,reddit和一些随机博客上查看了一些答案,所有这些都似乎已经过时,无论是旧的还是不起作用。
我正在使用我们在Django中获得的默认管理视图添加所有这些信息。我现在不确定如何解决这个问题。我不想要多个FileField,因为章节中的页面数是未知的。任何提示?
我的models.py是这样的:
from django.db import models
from django import forms
def book_upload_location(instance, filename):
return '{}/{}'.format(instance.book_name, filename)
def book_chapter_upload_location(instance, filename):
# /media/book_Name/Chapter_Number/
return '{}/{}/{}'.format(instance.book.book_name, instance.chapter_number, filename)
class book(models.Model):
book_name = models.CharField(max_length=500)
book_description = models.TextField(max_length=4000)
book_author = models.CharField(max_length=250)
book_genre = models.CharField(max_length=100)
book_image = models.FileField(upload_to=book_upload_location)
def __str__(self):
return str(self.book_name) + " ( " + str(self.pk) + ")"
class bookChapter(models.Model):
book = models.ForeignKey(book, on_delete=models.CASCADE) # Let's delete all the chapters related to a particular book, if book is deleted.
chapter_title = models.CharField(max_length=1000)
chapter_number = models.CharField(max_length=1000)
create_time = models.DateTimeField(auto_now_add=True)
chapter_images = models.FileField(upload_to=book_chapter_upload_location, widget=forms.ClearableFileInput(attrs={'multiple': True}))
def __str__(self):
return str(self.book.book_name) + " - " + " C" + str(self.chapter_number)
编辑:所以,正如@neverwalkaloner建议的那样,我改变了我的代码以进行“解决方法”并且我遇到了新的错误。
AttributeError: 'bookChapterFiles' object has no attribute 'book'
我的Models.py
来自django.db导入模型 来自django进口表格
def book_upload_location(instance, filename):
return '{}/{}'.format(instance.book_name, filename)
def book_chapter_upload_location(instance, filename):
return '{}/{}/{}'.format(instance.book.book_name, instance.chapter.chapter_number, filename)
class book(models.Model):
book_name = models.CharField(max_length=500)
book_description = models.TextField(max_length=4000)
book_author = models.CharField(max_length=250)
book_genre = models.CharField(max_length=100)
book_image = models.FileField(upload_to=book_upload_location)
def __str__(self):
return str(self.book_name) + " ( " + str(self.pk) + ")"
class bookChapter(models.Model):
book = models.ForeignKey(book,
on_delete=models.CASCADE) # Let's delete all the chapters related to a particular book, if book is deleted.
print("My book : %s" % book)
chapter_title = models.CharField(max_length=1000)
chapter_number = models.CharField(max_length=1000)
chapter_volume = models.CharField(max_length=1000, default=0)
create_time = models.DateTimeField(auto_now_add=True)
# chapter_images = models.FileField(upload_to=book_chapter_upload_location)
def __str__(self):
return str(self.book.book_name) + " - " + "V" + str(self.chapter_volume) + " C" + str(self.chapter_number)
class bookChapterFiles(models.Model):
chapter = models.ForeignKey(bookChapter, on_delete=models.CASCADE)
chapter_images = models.FileField(upload_to=book_chapter_upload_location)
我的Admin.py:
来自django.contrib import admin from books.models import book,bookChapter,bookChapterFiles
# class PageFileInline(admin.TabularInline):
# model = bookChapter
#
#
# class PageAdmin(admin.ModelAdmin):
# inlines = [PageFileInline, ]
class ChapterInline(admin.TabularInline):
model = bookChapterFiles
class bookAdmin(admin.ModelAdmin):
inlines = [
ChapterInline,
]
admin.site.register(bookChapter, bookAdmin)
admin.site.register(book)
答案 0 :(得分:1)
您的属性错误似乎来自您对类和属性的命名。 特别是在你的模型书中。第二章:
class bookChapter(models.Model):
book = models.ForeignKey(book, on_delete=models.CASCADE)
将图书模型的名称更改为" Book"而不是" book"。
我不确定django将如何处理您的命名约定。对我来说,这似乎是问题所在。您正在使用小写字母为您建模#34;预订"和你的bookChapter的属性" book",并在课堂上引用它们。即使它正在工作,也会令人困惑!
改变这个:
class book(models.Model):
book_name = models.CharField(max_length=500)
book_description = models.TextField(max_length=4000)
book_author = models.CharField(max_length=250)
book_genre = models.CharField(max_length=100)
book_image = models.FileField(upload_to=book_upload_location)
def __str__(self):
return str(self.book_name) + " ( " + str(self.pk) + ")"
class bookChapter(models.Model):
book = models.ForeignKey(book, on_delete=models.CASCADE)
对此:
class Book(models.Model):
name = models.CharField(max_length=500)
description = models.TextField(max_length=4000)
author = models.CharField(max_length=250)
genre = models.CharField(max_length=100)
image = models.FileField(upload_to=book_upload_location)
def __str__(self):
return str(self.name) + " ( " + str(self.pk) + ")"
class BookChapter(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE)
您应该考虑使用大写字母作为您的班级名称。 你打电话给你的书模型"预订",但因为它是一个课你应该叫它" Book"。 书籍模型的属性名称也是多余的。前缀"书_"对于书籍类的名称,描述和作者字段,您只需键入" book"两次。 例如:
book.book_name()
应该是:
Book.name()
答案 1 :(得分:0)
尝试使用AdminInline。你的admin.py应该是这样的:
from django.contrib import admin
from .models import book, bookChapter
class ChapterInline(admin.TabularInline):
model = bookChapter
class BookAdmin(admin.ModelAdmin):
inlines = [
ChapterInline,
]
admin.site.register(book, BookAdmin)
<强>更新强>
我认为book_chapter_upload_location
函数中存在新错误。你在那里打电话给instance.book
:
return '{}/{}/{}'.format(instance.book.book_name, instance.chapter.chapter_number, filename)
但bookChapterFiles没有book
属性。尝试改变它:
return '{}/{}/{}'.format(instance.chapter.book.book_name, instance.chapter.chapter_number, filename)