在Django Admin中使用内联的OneToOneField

AC *_*art 5 python django django-admin

我有DataFile模型,它们有LogOutput对象.一个数据文件对象将有一个LogOutput.对于属于DataFile的任何LogOutput,它只属于单个DataFile.其他模型也有LogOutput对象.

因为它们是一对一的,除了LogOutputs可以属于DataFiles以外的东西(例如,套件也有它们 - 参见下面的代码)我认为正确的做法是在DataFile中定义一个OneToOneField ,即该LogOutput.

models.py:

class LogOutput(models.Model):
    raw = models.TextField()

class DataFile(models.Model):
    name = models.CharField()#etc.
    logoutput = models.OneToOneField(LogOutput)

class Suite(models.Model):
    # Many Suites will have the same datafile:
    datafile = models.ForeignKey(DataFile)

    # Each Suite has a unique LogOutput different from the DataFile's
    # and as with the DataFile, that LogOutput will have just one Suite
    logoutput = models.OneToOneField(LogOutput)
Run Code Online (Sandbox Code Playgroud)

现在,当我在Admin视图中查看DataFile时,我想看到LogOutput,所以我想我会内联它.

admin.py:

class LogOutputInline(admin.TabularInline):
    model = LogOutput

class DataFileAdmin(admin.ModelAdmin):
    search_fields = ['name']
    inlines = [LogOutputInline]

admin.site.register(DataFile, DataFileAdmin)
Run Code Online (Sandbox Code Playgroud)

看来,由于OneToOneField定义的方向性,我无法进行内联.上面的admin.py给了我:

<class 'trial.models.LogOutput'> has no ForeignKey to <class 'trial.models.DataFile'>
Run Code Online (Sandbox Code Playgroud)

当然这是正确的,但我不知道它是如何相关的,因为DataFile只有一个(并且只有一个)LogOutput,而LogOutput只属于这一个DataFile.

我读了问题1744203,但解决方案是扭转关系的方向.我不认为我能做到这一点,因为其他对象(套件)也有LogOutputs.

而且,如果重要的话,这是在Django 1.5中.

我的问题是:为了在DataFile的管理页面上显示内联LogOutput,我需要做什么?(或者我是否想要使用需要修改的OneToOneField?)

TIA!

lyn*_*ynx 5

还有一个 django 插件可以内联,而不必反转 OneToOneField(s) 的方向:django_reverse_admin

您需要将 django_reverse_admin 添加到您的 requirements.txt:

-e git+https://github.com/anziem/django_reverse_admin.git#egg=django_reverse_admin
Run Code Online (Sandbox Code Playgroud)

然后导入:

管理文件

from django_reverse_admin import ReverseModelAdmin

# don't need to define an inline for LogOutput

class DataFileAdmin(ReverseModelAdmin):
    search_fields = ['name']
    inline_reverse = ['logoutput']
    inline_type = 'tabular'  # or could be 'stacked'

admin.site.register(DataFile, DataFileAdmin)
Run Code Online (Sandbox Code Playgroud)


小智 3

内部 ORM 和管理非常智能,但是当 OOP 遇到表结构时,事情可能会有点不精确。我建议通过使用如下所示的抽象基类来给 ORM 一些提示:

class LogOutput(models.Model):
    raw = models.TextField()

    class Meta:
        abstract = True

class DataFileLogOutput(LogOutput):
    pass

class SuiteFileLogOutput(LogOutput):
    pass

class DataFile(models.Model):
    name = models.CharField()#etc.
    logoutput = models.OneToOneField(DataFileLogOutput)

class Suite(models.Model):
    # Many Suites will have the same datafile:
    datafile = models.ForeignKey(DataFile)

    # Each Suite has a unique LogOutput different from the DataFile's
    # and as with the DataFile, that LogOutput will have just one Suite
    logoutput = models.OneToOneField(SuiteLogOutput)
Run Code Online (Sandbox Code Playgroud)