django admin内联抽象类和m2m字段

时间:2013-12-14 07:29:01

标签: django django-admin

这个问题几乎让我发疯:(

我试图在管理界面中使用StackedInline。 下面的代码在django文档中。

model.py

class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

admin.py

class MembershipInline(admin.StackedInline):
    model = Membership
    extra = 1

class PersonAdmin(admin.ModelAdmin):
    inlines = (MembershipInline,)

class GroupAdmin(admin.ModelAdmin):
    inlines = (MembershipInline,)

但是如果Group是一个抽象基类,而PublicGroup是继承自Group的子类。成员资格用于关联PublicGroup和Person。

class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='%(class)s_Membership')

    class Meta:
        abstract = True

class PublicGroup(Group):
    pass

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

运行命令后

python manage.py sql test

我收到错误“AssertionError:ForeignKey无法定义与抽象类组的关系”。 在搜索解决方案后,我知道外键不能指向抽象类。一些解决方案建议使用通用关系。所以我再次更改代码。

class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = generic.GenericRelation('Membership')

    class Meta:
        abstract = True

class PublicGroup(Group):
    pass

class Membership(models.Model):
    person = models.ForeignKey(Person)
    content_type = models.ForieignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey()
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)

这次是命令

python manage.py sql test

不会返回错误。但是当我尝试在管理界面上添加数据时出错。该错误表示Membership不是PublicGroup的外键。 StackedInline仍然无法正常工作。

现在我真的不知道该怎么做。有谁知道如何实现这个功能。 谢谢你的阅读!

2 个答案:

答案 0 :(得分:0)

你有什么理由使用它吗?

    class Meta:
        abstract = True

如果可能,请删除它,然后重建数据库。

您可能会感兴趣的是阅读this stackoverflow question about the difference between abstract models and regular inheritance的答案。

答案 1 :(得分:0)

您的模型结构非常糟糕:M2M关系会为您尝试连接的两个模型建立关系表,就像M2M字段中的“Through keyword

正如我所看到的,您只想基于Group在Person和Model之间建立M2M关系。

class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    type = models.CharField(max_lenght=32) # The Type of Group (Public/Private/etc..)
    members = models.ManyToManyField(Person, through='Membership')

class Membership(models.Model):
    person = models.ForeignKey(Person)
    group = models.ForeignKey(Group)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)