【问题标题】:django admin inline with abstract class and m2m field带有抽象类和 m2m 字段的 django admin 内联
【发布时间】:2014-01-02 01:36:04
【问题描述】:

这个问题几乎把我逼疯了:(

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

模型.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 无法定义与抽象类 Group 的关系”。 搜索解决方案后,我知道外键不能指向抽象类。一些解决方案建议使用泛型关系。所以我又改了代码。

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 仍然不起作用。

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

【问题讨论】:

    标签: django django-admin


    【解决方案1】:

    你有什么好的理由使用它吗?

        class Meta:
            abstract = True
    

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

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

    【讨论】:

    • 因为through='%(class)s_Membership'只适用于抽象类。
    • 我已经阅读了那个答案,我认为我需要 Group 成为抽象类。
    【解决方案2】:

    您的模型结构很糟糕: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)
    

    【讨论】:

      猜你喜欢
      • 2014-12-28
      • 1970-01-01
      • 2016-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-15
      • 2015-09-29
      相关资源
      最近更新 更多