是否可以创建没有背后模型的自定义管理视图

34

我有一个对象,我想在管理员(admin)中使用它,而不是继承models.Model的模型。如果我让它继承models.Model,这个对象将会在数据库中创建一个表,我不想要这样。我只想让这个对象保留在内存中。

我从stackoverflow网站上得到的一个解决方案是,我创建一个admin视图,并通过modelAdmin ( admin.site.register() ) 在admin.py中注册这些自定义视图,并将这个类似于模型的对象用作动态数据存储(在内存中)。

由于这个类似于模型的对象没有继承models.Model,admin.site.register() (在admin.py中)不接受它,并且当我尝试在浏览器中访问它时会显示一个“type”对象不可迭代的错误。


您可以将额外的视图连接到特定模型(并在其中执行与模型相关或不相关的任何操作;如果您喜欢,我可以发布一个包含此解决方案的答案),但我不知道有任何方法可以创建纯独立的管理视图,除非破解管理源代码。 - eternicode
@eternicode 实际上可以完全创建独立的管理视图:请参阅我的答案。 - Daniel Roseman
@Daniel Roseman,啊哈,原来如此!我从未见过这样的功能,尽管说实话我还没有需要它。 - eternicode
3个回答

26

嗯,感谢大家的帮助。我在你们的帮助下想出了以下解决方案:

我有两个自定义模板:

   my_model_list.html
   my_model_detail.html

在views.py文件中:

class MyModel(object):
    # ... Access other models
    # ... process / normalise data 
    # ... store data

@staff_member_required
def my_model_list_view(request) #show list of all objects
    #. . . create objects of MyModel . . .
    #. . . call their processing methods . . .
    #. . . store in context variable . . . 
    r = render_to_response('admin/myapp/my_model_list.html', context, RequestContext(request))
    return HttpResponse(r)

@staff_member_required
def my_model_detail_view(request, row_id) # Shows one row (all values in the object) in detail     
    #. . . create object of MyModel . . .
    #. . . call it's methods . . .
    #. . . store in context variable . . . 
    r = render_to_response('admin/myapp/my_model_detail.html', context, RequestContext(request))
    return HttpResponse(r)

在 Django 的主 urls.py 文件中:

urlpatterns = patterns( 
    '',
    (r'^admin/myapp/mymodel/$', my_model_list_view),
    (r'^admin/myapp/mymodel/(\d+)/$', my_model_detail_view),
    ( r'^admin/', include( admin.site.urls ) )
)

1
很高兴你自己解决了这个问题。我正要发表同样的评论。没有模型的管理视图基本上只是使用管理员模板和模拟ModelAdmin实例的普通Django视图,这就是你正在做的事情。我自己也曾这样做过,以创建一些自定义的管理主题页面。 - Cerin

8
您可以直接将您的视图添加到 AdminSite 对象中,而不是添加到任何特定的 ModelAdmin 子类中并进行注册。
默认的 AdminSite 可以通过 django.contrib.admin.site 访问,这是您在其上调用 register 和 autodiscover 的方法。您可以创建自己的子类,并向其中添加您自己的视图,然后对该子类进行注册,而不是对默认子类进行注册。请参阅此处了解更多信息。

有趣;我假设这些子类是通过一个“autodiscover”调用来获取的?或者你的子类需要在整个站点的应用程序中使用才能发挥作用?(实际上,我觉得我没有正确理解这个概念...) - eternicode
感谢您的帮助,丹尼尔!下面是解决方案,虽然我不完全确定这是否是您想要的。无论如何,它可以工作! :) - sysasa

5
最直接的答案是“不行”。正如Django Book所说,管理后台是为了“信任的用户编辑结构化内容”,在这种情况下,结构化内容是通过settings.py配置的层次结构模型。更重要的是,如果您的对象不完全符合models.Model的预期关系类型,则管理后台可能会在各个地方抛出异常。
然而,正如口号所说,“它只是Python”。您可以覆盖管理后台中的任何页面。只需在项目中创建自己的模板,并使它们在模板搜索中排在首位。此外,通过继承admin/base.html,您可以保持管理项目的外观和感觉。
为此对象编写您的管理视图和模板,就像处理其他对象一样,但要确保将视图包装在is_staff装饰器中,以确保未经授权的用户无法访问视图。将其放在应用程序中,可能在admin/views.py中,带有templates/admin/object_list.html和object_form.html。
一旦您为这些非数据库对象提供了适当的管理工具,您就可以通过管理索引页面提供对它们的访问:您想覆盖admin/index.html,并根据需要提供额外的项目特定项到页面中。
我已经完全做到了这一点,以便提供对第三方API的管理访问,这些API存储我们的数据,例如ConstantContact电子邮件服务,它的效果非常好。

谢谢你的帮助,Elf。我已经在下面发布了我的解决方案答案,但我不确定是否完全遵循了你的建议。 - sysasa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接