django admin中的通用多对多关系

django admin中的通用多对多关系,django,generics,django-admin,many-to-many,Django,Generics,Django Admin,Many To Many,我在Django有几款类似的车型: class Material(models.Model): title = models.CharField(max_length=255) class Meta: abstract = True class News(Material): state = models.PositiveSmallIntegerField(choices=NEWS_STATE_CHOICES) class Article(Materi

我在Django有几款类似的车型:

class Material(models.Model):
    title = models.CharField(max_length=255)
    class Meta:
        abstract = True

class News(Material):
    state = models.PositiveSmallIntegerField(choices=NEWS_STATE_CHOICES)

class Article(Material):
    genre = models.ForeignKey(Genre, verbose_name='genre')
以及与新闻和文章相关的模型主题

我想使用通用的多对多关系,就像这样。但问题是如何在django admin中使用默认的多个小部件。或另一个方便的模拟

UPD:如果我不使用泛型,我会写

class News(Material): 
    topic = models.ManyToMany(Topic) 

class Article(Material):
    topic = models.ManyToMany(Topic)
我会得到两个相同的表来表达这些关系。我想知道是否可以使用泛型来创建一个中间表,因为在我的数据库中,不仅新闻和文章可能有主题。新闻和文章也可能与两个或两个以上的主题相关联。

编辑:查看此链接

遗憾的是,GenericForeignKey的支持不如ForeignKey的好。有一个开放(并接受)的票证和补丁,用于为他们提供小部件:

开箱即用的是使用GenericForeignKey内联管理对象

假设你的一般关系是通过

from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.db import models

class News(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')
    ...

如果要编辑主题的新闻,可以为新闻定义内联管理员:

from django.contrib.contenttypes.generic import GenericTabularInline

class NewsInline(GenericTabularInline):
    model = News
并将其添加到主题管理的内联:

class TopicAdmin(models.ModelAdmin):
    inlines = (NewsInline, )
也就是说,从所提供的信息来看,我看不出你的多人关系有什么问题。它似乎表达了你的需要

也许你是在主题中定义了许多领域,而不是在新闻和文章中?在新闻和文章中定义它们

编辑:谢谢你的澄清。您的模型设置将按照arie的帖子(即相反的方式)进行,您将在线编辑。如果您只想从新闻/文章/等实例中选择现有主题,我不知道是否有任何现成的通用关系(它通常只是用作反向查找帮助器)。你可以

a) 根据GenericRelation覆盖管理表单并使用queryset添加ModelMultipleChiceField

b) 重写save()以调整关系


相当多的工作。我个人会坚持使用多个m2m表,而不是将所有内容都塞进一个表中。如果您在询问一个或多个主题的所有新闻和文章等时害怕数据库进行多次查找,那么请注意,通用解决方案将始终具有与GenericForeignKey所具有的要求类似的设置,即模型和id的附加列。这可能会导致更多查询(例如,针对每个结果的内容类型)。

如果您只是将Danny的示例转过来,并在
主题
-Model一侧定义泛型关系,这难道不管用吗

参见django文档中的示例:

根据这一问题:

class Topic(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey("content_type", "object_id")
在每个相关模型上额外定义属性可能是有意义的

class News(models.Model):
    topics = generic.GenericRelation(Topic)
现在,您可以创建一个主题行,并将主题附加到新闻、文章等内容中

class TopicInline(generic.GenericTabularInline):
    model = Topic

class ArticleAdmin(admin.ModelAdmin):
    inlines = [
        TopicInline,
    ]

class NewsAdmin(admin.ModelAdmin):
    inlines = [
        TopicInline,
    ]

不确定您链接到的问题是如何关联的。是否要从与Topic具有多个关系切换到为Topic提供一个GenericForeignKey,以便您可以“附加”它指向任何对象?您希望多选择列表小部件朝哪个方向?选择其主题的新闻?如果是一般关系,则主题的选择列表必须显示所有内容。我有点困惑。不过,在您的变体中,我打开主题条目并选择(或添加/删除)新闻和文章的新和平。这不是我想要的。我更新了问题。谢谢,但我几乎没有注意到你的编辑。我在github上看过django-generic-m2m应用程序,但我不知道如何将其应用到django管理员。我正在尝试使用你的答案,但我被卡住了。想法?但如果主题已经创建,我可以使用Tabu选择它吗拉林林?
class TopicInline(generic.GenericTabularInline):
    model = Topic

class ArticleAdmin(admin.ModelAdmin):
    inlines = [
        TopicInline,
    ]

class NewsAdmin(admin.ModelAdmin):
    inlines = [
        TopicInline,
    ]