首页 文章

在Django中通过Admin和Model上传多个文件

提问于
浏览
0

我正在构建一个非常基本的应用程序(我的第一个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导入管理员来自books.models导入书籍,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)

2 回答

  • 0

    您的属性错误似乎来自您对类和属性的命名 . 特别是你的模型书内部章节:

    class bookChapter(models.Model):
    book = models.ForeignKey(book, on_delete=models.CASCADE)
    

    将图书模型的名称更改为“预订”而不是“预订” .

    我不确定django将如何处理您的命名约定 . 对我来说,这似乎是问题所在 . 您使用小写字母为“model”和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)
    

    您应该考虑使用大写字母作为您的 class 名称 . 你打电话给你的书模型“书”,但因为它是一个类,你应该称之为“书” . 书籍模型的属性名称也是多余的 . 将“book_”添加到书籍类的名称,描述和作者字段之前只需要输入“book”两次 . 例如:

    book.book_name()
    

    它应该是:

    Book.name()
    
  • 1

    尝试使用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)
    

    UPDATE

    我认为新错误在 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)
    

相关问题