2012-12-17 46 views
8

比方说,我有一个Post对象,可以包含图像,视频和其他媒体类型。我可以使用GenericForeignKey将它们链接在一起。喜欢的东西:GenericForeignKey和Django中的管理员

class Post(models.Model): 
    title = models.CharField(...) 
    text = models.TextField(...) 

class AudioMedia(models.Model): 
    ... 

class VideoMedia(models.Model): 
    ... 

class ImageMedia(models.Model): 
    ... 

class MediaObject(models.Model): 
    post = models.ForeignKey(Post) 
    order = models.IntegerField() 

    content_type_media = models.ForeignKey(
    ContentType, limit_choices_to={ 
     'model__in': (
     'audiomedia', 
     'imagemedia', 
     'videomedia') 
    }) 

    object_id_media = models.PositiveIntegerField() 
    obj = generic.GenericForeignKey('content_type_media', 'object_id_media') 

现在,我可以很容易地创建一个管理界面,如:

class MediaObjectAdminInLine(admin.StackedInline): 
    model = MediaObject 
    ct_field = "content_type_media" 
    ct_fk_field = "object_id_media" 
    extra = 0 

class PostAdmin(admin.ModelAdmin): 
    inlines = [MediaObjectAdminInLine] 

现在问题:)在管理员/,我可以很容易地创建一个新的帖子。对于这篇文章,我可以轻松添加更多的MediaObject。在面板中,我有一个下拉菜单来选择类型(音频,视频,...),但我必须手动输入我想与Post链接的对象的ID。

我尝试过各种扩展,包括grappelli。有些提供了查找这些链接的对象的能力。我希望能够在这里添加对象,例如添加一个AudioMedia,一个VideoMedia,一个ImageMedia,这取决于我从下拉列表中选择什么。

有什么建议吗?

+0

我还没有尝试过,但一个想法 - 你能不能有一个管理表单,并且该表单覆盖'object_id'的默认文本框是一个'ModelChoiceField'? – karthikr

回答

4

你需要做相当多的工作才能实现这一目标。

  • 您要求管理员根据从下拉列表中选择的模型类型,动态显示模型表单。
  • Django的管理员没有这样做(也没有做任何已知的扩展)。

为了使这项工作,你必须:

  1. 编写自定义JavaScript事件处理程序捕获模式选择降的下来电平变化。
  2. 然后调用Django的管理员并请求该模型的内联模型。
  3. 使用该模型窗体更新当前HTML页面。
  4. 然后,您需要拦截父模型的modelform的save()方法,以确定它处理的是哪个子模型,并将其正确保存到数据库中。
  5. 然后,您需要理清如何获得父模型的模型,以便根据子模型正确显示适当的子模型的模型表单。

听起来令人畏缩?它是。

这里有一个更简单的方法:

只有一个“媒体”模型。你会在模型上有几个只对你的类型有效的字段(尽管有很多交叉)。

命名特定于具有该媒体类型前缀的单个媒体类型的任何字段,即image_size', or video_title`。

将JavaScript处理程序附加到您的ModelAdmin中,该处理程序根据媒体类型的下拉列表选择性地显示和隐藏字段。这样的事情:

​​
0

django-admin-genericfk不支持Django 1.9。

除此之外,我只发现了以下模块:

https://github.com/lexich/genericrelationview

看起来良好的维护。不幸的是,它的JS代码与Django CMS如何设置jQuery(noConflict jQuery)并不一致,所以它似乎不适合我。但它应该没问题,如果不是在Django CMS页面中使用,而是使用常规的Django Admin。