以下是我的简化模型:
from django.contrib.contenttypes.fields import (
GenericForeignKey, GenericRelation)
from django.db import models
from django.utils.translation import ugettext_lazy as _
class Thing(models.Model):
'''
Our 'Thing' class
with a link (generic relationship) to an abstract config
'''
name = models.CharField(
max_length=128, blank=True,
verbose_name=_(u'Name of my thing'))
# Link to our configs
config_content_type = models.ForeignKey(
ContentType,
null=True,
blank=True)
config_object_id = models.PositiveIntegerField(
null=True,
blank=True)
config_object = GenericForeignKey(
'config_content_type',
'config_object_id')
class Config(models.Model):
'''
Base class for custom Configs
'''
class Meta:
abstract = True
name = models.CharField(
max_length=128, blank=True,
verbose_name=_(u'Config Name'))
thing = GenericRelation(
Thing,
related_query_name='config')
class FirstConfig(Config):
pass
class SecondConfig(Config):
pass
以下是管理员:
from django.contrib import admin
from .models import FirstConfig, SecondConfig, Thing
class FirstConfigInline(admin.StackedInline):
model = FirstConfig
class SecondConfigInline(admin.StackedInline):
model = SecondConfig
class ThingAdmin(admin.ModelAdmin):
model = Thing
def get_inline_instances(self, request, obj=None):
'''
Returns our Thing Config inline
'''
if obj is not None:
m_name = obj.config_object._meta.model_name
if m_name == "firstconfig":
return [FirstConfigInline(self.model, self.admin_site), ]
elif m_name == "secondconfig":
return [SecondConfigInline(self.model, self.admin_site), ]
return []
admin.site.register(Thing, ThingAdmin)
到目前为止,我已经将FirstConfig对象链接在一起的Thing对象。 代码被简化:在一个不相关的部分,我设法在Thing创建时创建我的抽象Config并设置正确的content_type / object_id。
现在我想在我的ThingAdmin中看到这个FirstConfig实例作为内联(FirstConfigInline)。
我尝试使用django.contrib.contenttypes.admin.GenericStackedInline,但它不适用于我当前的模型设置。
我尝试使用我的FirstConfigInline的fk_name
参数
另外,正如你所看到的,我试图用“''我的配置模型上的GenericRelation属性,没有成功..
有关如何正确设置管理员的任何想法吗?
答案 0 :(得分:0)
根据Django Docs,您必须定义ct_fk_field和ct_field(如果它们已从默认值更改)。因此将ct_field设置为config_content_type可能就足够了。
希望它有效!
编辑:必须在内联中声明这些值:
class SecondConfigInline(admin.StackedInline):
model = SecondConfig
ct_fk_field = "config_object_id"
ct_field = "config_content_type"
EDIT2:
我刚刚在我的假设中意识到错误。通常,您应该在Inline模型中声明Foreignkey。根据您的其余代码,您可以删除Thing上的通用外键+ Config上的genericRelation,并在Config-Basemodel上声明一个正常的外键。
答案 1 :(得分:0)
这个问题很旧,但是我还是尝试一下。
我认为解决方案取决于您打算在Thing
和Config
子类之间创建什么样的关系。
当前设置的方式看起来像多对一关系:每个Thing
指向一个单独的Config
子类,许多Thing
可以指向相同的Config
子类。由于具有通用关系,每个Thing
都可以指向不同的模型(不一定要Config
的子类,除非您做一些额外的工作)。
在这种情况下,我想将内联放置在Config
的管理员身上会更有意义。也就是说,为GenericStackedInline
(具有Thing
)创建一个GenericForeignkey
,并将内联添加到ConfigAdmin
,然后可以将其用于所有{{1} }子类。另请参见下面的示例。然后,通用内联会自动设置正确的Config
和content_type
。
另一方面,如果您要在object_id
和每个Thing
子类之间寻找多对多关系,则可以将Config
移到单独的多对多表(将其称为GenericForeignkey
)。
一些代码可以说一千多个单词,所以让我们按如下方式拆分ThingConfigRelation
类:
Thing
现在可以在class Thing(models.Model):
name = models.CharField(max_length=128)
class ThingConfigRelation(models.Model):
thing = models.ForeignKey(to=Thing, on_delete=models.CASCADE)
content_type = models.ForeignKey(ContentType, null=True, blank=True,
on_delete=models.CASCADE)
object_id = models.PositiveIntegerField(null=True, blank=True)
config_object = GenericForeignKey(ct_field='content_type',
fk_field='object_id')
中添加内联了。以下是适用于关系双方的管理员的准系统示例:
ThingAdmin
请注意,我们在关系的from django.contrib import admin
from django.contrib.contenttypes.admin import GenericStackedInline
from .models import Thing, FirstConfig, SecondConfig, ThingConfigRelation
class ConventionalTCRInline(admin.StackedInline):
model = ThingConfigRelation
extra = 0
class GenericTCRInline(GenericStackedInline):
model = ThingConfigRelation
extra = 0
class ThingAdmin(admin.ModelAdmin):
inlines = [ConventionalTCRInline]
class ConfigAdmin(admin.ModelAdmin):
inlines = [GenericTCRInline]
admin.site.register(Thing, ThingAdmin)
admin.site.register(FirstConfig, ConfigAdmin)
admin.site.register(SecondConfig, ConfigAdmin)
侧(即ForeignKey
)中使用常规内联,而在ThingAdmin
侧({ {1}}。
一个棘手的事情是过滤GenericForeignKey
上的ConfigAdmin
和content_type
字段。
另一种选择可能是完全摆脱object_id
并使用某种具有普通旧ThingAdmin
的单表继承实现,有点像this。