Python-Django中的两级层次结构

时间:2014-04-29 20:06:44

标签: python django model

我的课程设计存在问题。

我需要的是能够获取通过管理员上传的最新媒体文件。媒体文件可以是歌曲,专辑和视频。

所以我有下一个课程:

class MediaFile(models.Model):
    name = models.CharField(max_length=50)
    created_at = models.DateTimeField(auto_now_add=True)
    last_update = models.DateTimeField(auto_now=True)

class Song(models.Model):
    media_data = models.OneToOneField(to=MediaFile) # relation with MediaFile
    file = models.FileField(upload_to='mp3')
    album = models.ManyToManyField(Album)

class Album(models.Model):
    media_data = models.OneToOneField(to=MediaFile) # relation with MediaFile
    cover = models.ImageField(upload_to='albums')
    release_date = models.DateField()

class Video(models.Model):
    media_data = models.OneToOneField(to=MediaFile) # relation with MediaFile
    summary = models.TextField()

验证确定,但是当我运行项目时,它会返回下一个错误:

<class 'MediaFile'> has no ForeignKey to <class 'Song'>

那么,你知道我做错了什么吗?你知道有没有更好的方法来实现这个目标?我的意思是,我必须实现的是能够上传最后10个媒体文件,而不必获得第一行歌曲,然后是专辑,然后是视频。

我接受批评和建议,谢谢!

修改

此处发生错误: environment \ lib \ site-packages \ django \ forms \ models.py in _get_foreign_key,第942行

编辑2:

这是追溯

> Traceback Switch to copy-and-paste view

\environment\lib\site-packages\django\core\handlers\base.py in get_response
                    response = wrapped_callback(request, *callback_args, **callback_kwargs) ...
▶ Local vars
\environment\lib\site-packages\django\contrib\admin\options.py in wrapper
                return self.admin_site.admin_view(view)(*args, **kwargs) ...
▶ Local vars
\environment\lib\site-packages\django\utils\decorators.py in _wrapped_view
                    response = view_func(request, *args, **kwargs) ...
▶ Local vars
\environment\lib\site-packages\django\views\decorators\cache.py in _wrapped_view_func
        response = view_func(request, *args, **kwargs) ...
▶ Local vars
\environment\lib\site-packages\django\contrib\admin\sites.py in inner
            return view(request, *args, **kwargs) ...
▶ Local vars
\environment\lib\site-packages\django\utils\decorators.py in _wrapper
            return bound_func(*args, **kwargs) ...
▶ Local vars
\environment\lib\site-packages\django\utils\decorators.py in _wrapped_view
                    response = view_func(request, *args, **kwargs) ...
▶ Local vars
\environment\lib\site-packages\django\utils\decorators.py in bound_func
                return func(self, *args2, **kwargs2) ...
▶ Local vars
\environment\lib\site-packages\django\db\transaction.py in inner
                return func(*args, **kwargs) ...
▶ Local vars
\environment\lib\site-packages\django\contrib\admin\options.py in add_view
            for FormSet, inline in zip(self.get_formsets(request), inline_instances): ...
▶ Local vars
\environment\lib\site-packages\django\contrib\admin\options.py in get_formsets
            yield inline.get_formset(request, obj) ...
▶ Local vars
\environment\lib\site-packages\django\contrib\admin\options.py in get_formset
            fields = flatten_fieldsets(self.get_fieldsets(request, obj)) ...
▶ Local vars
\environment\lib\site-packages\django\contrib\admin\options.py in get_fieldsets
        form = self.get_formset(request, obj, fields=None).form ...
▶ Local vars
\environment\lib\site-packages\django\contrib\admin\options.py in get_formset
        return inlineformset_factory(self.parent_model, self.model, **defaults) ...
▶ Local vars
\environment\lib\site-packages\django\forms\models.py in inlineformset_factory
    fk = _get_foreign_key(parent_model, model, fk_name=fk_name) ...
▶ Local vars
\environment\lib\site-packages\django\forms\models.py in _get_foreign_key
            raise Exception("%s has no ForeignKey to %s" % (model, parent_model)) ...
▶ Local vars

编辑3:

我在这里添加 admin.py

class SongInline(admin.TabularInline):
    model = Song

class AlbumAdmin(admin.ModelAdmin):
    inlines = [
        SongInline,
    ]


class MediaFileInline(admin.TabularInline):
    model = MediaFile

class MediaFileAdmin(admin.ModelAdmin):
    inlines = [
        MediaFileInline,
    ]

admin.site.register(MediaFile)
admin.site.register(Song, MediaFileAdmin)
admin.site.register(Video)
admin.site.register(Album, AlbumAdmin)

2 个答案:

答案 0 :(得分:0)

我相信正在发生的事情是Django出于完整性原因想要使用OneToOneField的主键(PK)。由于您的模型具有隐含PK(默认情况下为自动增量整数类型),因此它尝试将两个事物链接在一起,但在尝试获取对象时会碰到一个墙。在您的模型中尝试以下内容:

class Song(models.Model):
    media_data = models.OneToOneField(MediaFile, primary_key = True)
    file = models.FileField(upload_to='mp3')
    album = models.ManyToManyField(Album)

有关更多信息,请尝试: Django's OneToOne Documentation

答案 1 :(得分:0)

必须为在其上定义OneToOneField的模型定义内联。以下是你可以做的事情。

class SongInline(admin.TabularInline):
    model = Song

class AlbumInline(admin.TabularInline):
    model = Album

class VideoInline(admin.TabularInline):
    model = Video

class MediaFileAdmin(admin.ModelAdmin):
    inlines = [
        SongInline,
        AlbumInline,
        VideoInline
    ]

admin.site.register(MediaFile, MediaFileAdmin)
admin.site.register(Song)
admin.site.register(Video)
admin.site.register(Album)