Python 允许管理员通过视图控制Django ORM

Python 允许管理员通过视图控制Django ORM,python,django,Python,Django,我想向我的用户公开ORM控件。我不是说我想让他们在部分代码中添加东西,我是说我想让他们编写django代码。我只需要允许特定的模型,并且只允许获取数据(不添加或更改任何内容)。将有一个控制台,每一行都将被执行(有点像ipython笔记本),然后返回的数据(如果是QuerySet对象)将显示在某种类型的表中 此功能只对我的超级用户管理员可用,因此不会引起安全问题。最好的方法是什么(如果可能的话) 更新 也许我应该在这里给出一些预期用途的背景。看,我已经建立了一个应用程序,收集和保存统计信息。我的用

我想向我的用户公开ORM控件。我不是说我想让他们在部分代码中添加东西,我是说我想让他们编写django代码。我只需要允许特定的模型,并且只允许获取数据(不添加或更改任何内容)。将有一个控制台,每一行都将被执行(有点像ipython笔记本),然后返回的数据(如果是QuerySet对象)将显示在某种类型的表中

此功能只对我的超级用户管理员可用,因此不会引起安全问题。最好的方法是什么(如果可能的话)

更新

也许我应该在这里给出一些预期用途的背景。看,我已经建立了一个应用程序,收集和保存统计信息。我的用户有很多我为他们构建的过滤器,但他们不断要求越来越灵活,有时他们需要对一些非常具体的东西进行过滤,这只是一次性的事情,所以我不能一直添加越来越多的功能

现在我的超级用户懂一点python,我想也许我可以给他们一些自己过滤的方法。其想法是,他们将能够保存查询并命名它们,然后将这些自定义过滤器添加到主站点上的列表中

其工作方式是获得一个包含所有对象的QuerySet对象,可以使用预先确定的命令列表对其进行过滤。运行该命令后,服务器将对其进行评估,查找错误或禁止的代码,然后才运行该命令。但是我猜我不能在生产服务器中使用
eval()
,现在可以吗?那有别的办法吗

我想允许他们编写django代码

这意味着允许某些用户编写Django,并通过扩展Python来编写代码。如果不允许管理员用户终端访问实时计算机上的代码,这是不可能的。如果您允许终端访问代码,那将是一个安全问题,因为一个简单的语法错误可能会导致整个站点关闭

此外,如果您这样做,用户的每一次更改都需要重新同步数据库,并且存在一个真正的风险,即他们可能会对模型进行更改,使其
syncdb
,甚至无法处理,这意味着您的数据无法检索,站点无法正常运行


重新设计应用程序,以便通过更改对象实例而不是对象代码本身来提高灵活性。

在服务器上添加文件
/usr/local/sbin/djshell

#!/bin/sh
cd /path/to/project/
/path/to/python /path/to/project/manage.py shell #or "dbshell" or custom interactive task
使用此shell添加用户

useradd -s /usr/local/sbin/djshell -g www-data [more options] superdjangoadmin
允许通过ssh登录。用户直接连接到django shell,从app.models import*键入
,这就是您所需要的

从这个shell中,用户可以中断可访问的数据。您必须确保所有数据都是只读的。 可以使用settings.py的副本运行此操作,并使用只读用户名设置数据库

自定义shell的伪代码:


如果管理员知道SQL-给他们
phpmyadmin
只读权限。

经过一番周折后,我意识到我在寻找比我想象的简单得多的东西。下面是一个关于它的外观的快速概念(项目是一个带有两个字段的测试模型,email和name):

服务器端:

def qs_eval(request):
    items = Item.objects.all()
    code = ''
    if request.method == 'GET':
        code = request.GET['code']
        cleaned = map(lambda x: x.strip(), code.split(','))
        commands = dict([x.split('=') for x in cleaned if x])
        items = items.filter(**commands)        

    return render_to_response('qs_eval.html', {'items': items, 'code': code})
html:


发送!
名称
电子邮件
{items%%中的i的%s}
{{i.name}
{{i.email}
{%endfor%}
显然,这里没有错误处理,我只允许过滤,但很容易将其扩展到其他功能,如排除和其他功能,以及pythonical检查代码是否有任何不允许的功能等


不管怎样,这就是我最后要做的。我仍然会将@eri的建议作为答案,看看如何实现一个真正完整的控制台类型控件,这可能是正确的方向

没有好办法做到这一点。也许让Django管理第二个数据库。谢谢。不过有几点需要注意-1。首先,当我说django代码时,我只是指它的抽象。他们自己不会得到模型,但是,比如说,一个
MyModel.objects.all()
的QuerySet对象,他们可以对其进行筛选(除此之外什么都没有)。我只打算公开API的一小部分,并在运行它之前使用白名单对其进行评估。我看不出错误处理有什么问题,因为我可以扫描它们,而不返回任何内容(或以文本格式返回回溯)。谢谢,如果我真的想给它们shell控制,这是一个很好的答案,但这并不是我所需要的。我希望他们对基本过滤功能进行一些简化,以允许创建自定义查询。@yuvi编写自定义shell=)我自己的自定义shell是什么?这主意不错。我会想这不是我最终要做的,但我非常喜欢这个解决方案,它是我在问题中提到的真正控制台类型控件的正确方法。谢谢@yuvi更新了我的意思是说“定制外壳”,但他们没有。ThanksIt不适合复杂的查询我从来没有说过我需要复杂的查询限制和聚合是经常需要的
def qs_eval(request):
    items = Item.objects.all()
    code = ''
    if request.method == 'GET':
        code = request.GET['code']
        cleaned = map(lambda x: x.strip(), code.split(','))
        commands = dict([x.split('=') for x in cleaned if x])
        items = items.filter(**commands)        

    return render_to_response('qs_eval.html', {'items': items, 'code': code})
<form>
    <input type='text' name='code' value='{{ code }}' />
    <button cls='btn'>send!</button>
</form>

<table class='table'>
    <thead>
    <tr>
        <th>name</th>
        <th>email</th>
    </tr>
    </thead>

    <tbody>
    {% for i in items %}
        <tr>
            <td>{{ i.name }}</td>
            <td>{{ i.email }}</td>
        </tr>
    {% endfor %}
    </tbody>
</table>