2017-06-24 14 views
0

私は非常に基本的なアプリケーション(私の最初のDjangoアプリケーション)を構築しています。ユーザーがデータベースに本を追加したかったのです。だから、名前とイメージ(ブックカバー)とともに、本を追加するモデルが1つあります。Djangoの管理者とモデルを使って複数のファイルをアップロード

これはうまくいきます。さて、私はこの本の章をアップロードしたいと思いました。章には複数のページがあり、複数のファイル(.pdfファイルなど)があります。私は章の別のクラスを作り、このクラスをForeginKeyでリンクしました。

私はSO、reddit、いくつかのランダムなブログでいくつかの回答を見てきましたが、それらのすべては時代遅れであるか、古いか、動作していないようです。

私はDjangoで取得したデフォルトの管理ビューを使用してこの情報をすべて追加します。私は今これについてどうやって行くのか分かりません。章内のページ数が不明なので、私は複数のFileFieldを必要としません。何かヒント? @neverwalkalonerが示唆したように、私は「回避策」を行うには私のコードを変更し、私は新しいエラーを取得しています:だから、

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) 

EDIT:

私のmodels.pyはこのようなものです。 django.db輸入モデルジャンゴインポートフォームから

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から

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

マイModels.py

django.contrib輸入管理者から books.models from books、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

AdminInlineを使用してください。私は新しいエラーがbook_chapter_upload_location機能であると思い

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

:あなたadmin.pyは次のようになります。

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

しかしbookChapterFilesは book属性を持っていけない:あなたはそこに instance.bookを呼び出しています。それを変更してみてください:

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

示す '<クラス 'book.admin.BookAdmin'>:(admin.E104) 'book.models.bookChapter' 'から継承する必要がありますInlineModelAdmin'.' – Xonshiz

+0

@ Xonshizは答えを更新しました。 'inlines'リストでbookChapterをChapterInlineに置き換えてみてください。 – neverwalkaloner

+0

これは 'Book'の同じページにbookChapterを追加して、複数のファイルをアップロードするための複数のフィールドを与えてくれます。 bookChapterを個別に開き、複数のファイルをアップロードするためのボタンが1つ必要です。これは今起こっています:http://i.imgur.com/hDRfJwN.png – Xonshiz

1

あなたの属性のエラーは、クラスと属性の名前から来ているようです。具体的にあなたのモデルbookChapter内部 :

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

変更の代わりに「予約」のあなたの本モデルの「ブック」の名前。

私はdjangoがあなたの命名規則をいかにうまく処理するかは分かりません。私には、それは問題のように見えます。あなたはモデル "book"と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」を2回入力する必要があります。 例えば:

book.book_name() 

それでなければならない:

Book.name()