django admin中的通用多对多关系

San*_*4ez 5 generics django many-to-many django-admin

我在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')
Run Code Online (Sandbox Code Playgroud)

和模型主题,与新闻和文章相关的ManyToMany.

我想在这种情况下使用Generic多对多关系.但问题是如何在django admin中使用默认的ManyToMany小部件.或者另一种方便的模拟.

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

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

class Article(Material):
    topic = models.ManyToMany(Topic)
Run Code Online (Sandbox Code Playgroud)

我会得到2个相同的表来表达这些关系.我想知道我是否可以使用泛型来拥有一个中间表,因为不仅新闻和文章可能在我的数据库中有主题.新闻和文章也可能与2个或更多主题相关联.

Dan*_*air 7

编辑:检查这个http://charlesleifer.com/blog/connecting-anything-to-anything-with-django/

遗憾的是,GenericForeignKey不像ForeignKey那样得到支持.有一个打开(并接受)的票证,附带为他们提供小部件:http://code.djangoproject.com/ticket/9976

开箱即用的是使用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')
    ...
Run Code Online (Sandbox Code Playgroud)

class Topic(models.Model):
    ...
    news = generic.GenericRelation('News')   # if separate app: 'newsapp.News'
Run Code Online (Sandbox Code Playgroud)

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

from django.contrib.contenttypes.generic import GenericTabularInline

class NewsInline(GenericTabularInline):
    model = News
Run Code Online (Sandbox Code Playgroud)

并将其添加到主题管理员的内联中:

class TopicAdmin(models.ModelAdmin):
    inlines = (NewsInline, )
Run Code Online (Sandbox Code Playgroud)

也就是说,根据给出的信息,我看不出你的ManyToMany关系有什么问题.它似乎表达了你的需要.

也许你在Topic中定义ManyToMany字段而不是在News和Article中?在新闻和文章中定义它们.

编辑:谢谢你的澄清.您的模型设置将按照arie的帖子(即相反的方式)进行,并且您将进行内联编辑.如果您只想从新闻/文章/等内部选择现有主题.例如,我不知道GenericRelation的任何开箱即用(通常只是作为反向查找助手).你可以

a)覆盖管理表单,并根据GenericRelation添加带有查询集的ModelMultipleChoiceField

b)覆盖save()以调整关系.

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