通过Djang中的Admin和Model上传多个文件

2024-04-24 05:58:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在构建一个非常基本的应用程序(我的第一个Django应用程序)。我希望用户在数据库中添加一本书。所以,我有一个模型,它添加了一本书,以及它的名称和图像(封面)。在

这个很好用。现在,我想上传这本书的章节,一个章节会有多个页面,所以有多个文件(比如,.pdf文件)。我为章节做了另一个类,并通过ForeginKey链接了这个类。在

我在这里查看了一些答案,比如reddit和一些随机的博客,它们似乎都过时了,过时了或者不起作用。在

我使用Django中的默认管理视图添加所有这些信息。我不知道现在该怎么办。我不想要多个FileField,因为一章中的页数是未知的。有什么提示吗?在

我的模型.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)

编辑:所以,正如@neverwaltoner建议的那样,我修改了代码来做“变通方法”,我得到了新的错误。在

AttributeError: 'bookChapterFiles' object has no attribute 'book'

我的模型.py在

从django.db公司导入模型 从django导入表单

^{pr2}$

我的管理员py以下内容:

从django.contrib公司导入管理员 从书籍.模型导入书籍,书籍章节,书籍章节文件

# 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)

Tags: djangoinstancename模型selfadminmodelslength
2条回答

尝试使用AdminInline。你的管理员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那里:

^{pr2}$

但是bookChapterFiles没有book属性。尝试改变它:

return '{}/{}/{}'.format(instance.chapter.book.book_name, instance.chapter.chapter_number, filename)

你的属性错误似乎来自于你对类和属性的命名。 特别是在你的模型书章节:

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

将书本模型的名称改为“book”而不是“book”。在

我不确定django将如何处理您的命名约定。在我看来这就是问题所在。您使用小写字母为“book”和bookChapter的属性“book”建模,并在类中引用它们。即使有效,也令人困惑!在

更改此项:

^{pr2}$

为此:

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.book_name() 

它应该是:

Book.name() 

相关问题 更多 >