在我遇到不好的例子之前总结一下,et al:我正在尝试制作一个应用程序,我不必在所有模型中编写代码来限制对当前登录帐户的选择(I' m 不使用身份验证或帐户或登录的内置功能)。
即,我不想必须做这样的事情:
class Ticket(models.Model):
account = models.ForeignKey(Account)
client = models.ForeignKey(Client) # A client will be owned by one account.
content = models.CharField(max_length=255)
class TicketForm(forms.ModelForm):
class Meta:
model = Ticket
exclude = ('account',) #First sign of bad design?
def __init__(self, *args, **kwargs):
super(OrderForm, self).__init__(*args, **kwargs)
if self.initial.get('account'):
# Here's where it gets ugly IMHO. This seems almost
# as bad as hard coding data. It's not DRY either.
self.fields['client'].queryset = Client.objects.filter(account=self.initial.get('account'))
我的想法是使用以下自定义管理器创建一个 Account(models.Model)
模型,并使用我所有模型的多表继承对其进行子类化。不过,这让我感到非常头疼。我还需要在每个模型上使用 account
外键吗?我可以访问某个模型实例的父类帐户吗?
class TicketManager(models.Manager):
def get_query_set(self):
return super(TicketManager, self).get_query_set().filter(account=Account.objects.get(id=1))
# Obviously I don't want to hard code the account like this.
# I want to do something like this:
# return super(ProductManager, self).get_query_set().filter(account=self.account)
# Self being the current model that's using this manager
# (obviously this is wrong because you're not inside a model
# instance , but this is where the confusion comes in for me.
# How would I do this?).
请忽略任何明显的语法错误。我在这里输入了整个内容。
这就是我想到这样做的地方:Django Namespace project
最佳答案
对于 Django,有两个密切相关的问题。
一种是行级权限,其中用户/帐户需要特定权限才能查看表中的特定行(对象),这与具有表级权限的普通 Django 身份验证框架不同。
您链接到的项目是尝试实现行权限的多个项目之一。 django-granular-permissions是另一个和第三个(我最喜欢和最活跃/维护的)是django-authority .
即将发布的 Django 1.2 将具有 Hook ,使行级权限更易于实现,author of django-authority will work on integrating his project .
第二个相关问题是称为 Multi-Tenancy 数据库的东西,它是行权限的一种变体。在此方案中,您可能有来自单个公司的多个用户,例如,他们都可以访问该公司的数据,但不能访问其他公司(租户)。
我认为这不是您想要的,但您也许可以使用一些相同的技术。见 how to enforce account separation in Django和 multi-tenant django applications .两者的答案都很少,但都是一个起点,也是研究 Rails 应用程序和 this article 的 Multi-Tenancy 架构的起点。 .
至于您的问题的更具体的答案,我认为您应该使用 django-authority或编写自定义管理器并使用 record ownership screener在开发过程中验证您的查询没有绕过自定义管理器。
关于Django:如何组织这个大模型/经理/设计困惑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2134549/