最佳实践:为每个用户创建一个新表是个好主意?

Bas*_*sil 2 django database-design

我目前正在编写一个小的django应用程序,以便对框架进行一些练习.该应用程序允许用户登录,写入条目并查看其条目列表.我应该如何将条目分配给创建它们的用户?为每个新用户创建一个表并在那里保存条目是一个好主意,还是应该在条目模型中添加一个额外的字段(例如'created_by')并过滤要在列表中显示的项目?

需要考虑的一件事是,用户绝对不应该看到自己以外的条目(例如某些人使用应用程序写日记).这是两种方式吗?

我以前更新用过数据库,所以我很感激为什么一种方法比另一种更好.

Jim*_*Gaw 8

根据您的要求,为每个用户设置不同的数据库表会使事情变得更加困难,并且不值得权衡.举个例子:在"每个用户一个表"场景中,当你去检索用户的信息时,你必须弄清楚该用户表的名称是什么.我甚至不确定你是怎么做的,因为关于用户的信息存储在表本身中.(忽略会话存储.)

当您尝试将日记条目存储在自己的表中时,会出现更大的问题,并且您希望保持参照完整性.也就是说,您希望确保每个条目都属于实际存在的用户.对于每个用户来说,这几乎是不可能的.

可以很容易地为用户使用一个表,一个用于条目的表,以及将两个表连接起来而没有任何大的,有缺口的安全漏洞.你的"created_by"链接是要走的路.加载页面的视图功能可以轻松约束用户,因此他们只能看到自己的条目.这是一个观点:

@login_required
def my_entries(request):
    user = request.user
    entries = Entry.objects.filter(created_by=user)
    # return response here...
Run Code Online (Sandbox Code Playgroud)

@login_required是一个装饰器,需要登录用户访问页面,而Entry模型上的.filter()调用只会加载由加载页面的用户创建的条目.

现在,此列表可能链接到每个条目的"编辑"页面.每个页面的URL可能在URL中具有唯一标识符,通常是ID字段.因此,创建的第一个条目自动获得ID为1,下一个条目将获得ID为2,依此类推,因此标识每个条目的内容都是唯一的.所以URL可能看起来像'/ entry/1 /','/ entry/2 /'等.当页面加载时,它会检查URL中的ID.如果它为'1',则加载ID为'1'的条目供用户编辑.(对不起,如果您已经知道该部分.)

但是,这意味着,一个更精明的用户可能会弄​​清楚如何形成URL并开始输入他们自己的ID,作为侦察其他人的条目的手段.我可以开始输入带有随机ID值的URL,直到我找到一个加载:'/ entry/8 /'.也许我不拥有ID为8的条目,但从理论上讲,如果设置正确,我可以加载它.

有一些非常简单的方法可以阻止这种情况.当您编写用于加载单个条目的视图时,不要只通过其ID加载Entry实例...按其ID加载它,并通过以下方式创建用户:

@login_required
def get_entry(request, entry_id):
    user = request.user
    entry = Entry.objects.get(id=entry_id, created_by=user)
    # return response here...
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,如果我试图为存在的条目加载此页面,但这不属于我,则会引发异常.在Django中实际上有一个名为'get_object_or_404'的辅助方法可以帮助解决这个问题:

@login_required
def get_entry(request, entry_id):
    user = request.user
    entry = get_object_or_404(Entry, id=entry_id, created_by=user)
    # return response here...
Run Code Online (Sandbox Code Playgroud)

现在,如果我尝试访问存在的Entry实例的页面,但不是我的,我只会看到Django提供的典型"找不到页面"错误,如果我试图访问没有的页面存在.

我知道您的问题是关于用户数据库表,但我希望这可以帮助您配置Django,以便您的用户不会读取/编辑彼此的数据.