Django:如何组织这个大模特/经理/设计混乱? [英] Django: How would one organize this big model / manager / design mess?

查看:155
本文介绍了Django:如何组织这个大模特/经理/设计混乱?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我遇到错误的例子之前总结一下,等:我正在尝试一个应用程序,我不必在所有模型中编写代码来限制当前登录帐户的选择(我' m不使用Auth或用于帐户或登录的内置功能)。



即,我不要想要做某事这个:

  class Ticket(models.Model):
account = models.ForeignKey(Account)
client = models.ForeignKey(Client)#客户端将由一个帐户拥有。
content = models.CharField(max_length = 255)

class TicketForm(forms.ModelForm):
class Meta:
model = Ticket
exclude = ('account',)#设计不好的第一个标志?

def __init __(self,* args,** kwargs):
super(OrderForm,self).__ init __(* args,** kwargs)
if self.initial。 get('account'):
#这里是丑陋的IMHO。这似乎差不多
#与硬编码数据一样糟糕。它也不是干的。
self.fields ['client']。queryset = Client.objects.filter(account = self.initial.get('account'))

我的想法是使用以下自定义管理器创建一个帐户(models.Model)模型,并使用多个-table继承我所有的模型。这给我一个巨大的脑疼。每个型号还需要一个帐户外键吗?我可以访问某个模型实例的父类帐户吗?

  class TicketManager(models.Manager):
def get_query_set(self):
return super(TicketManager,self).get_query_set()。filter(account = Account.objects.get(id = 1))
#显然我不想硬代码这样的帐户。
#我想做这样的事情:
#return super(ProductManager,self).get_query_set()。filter(account = self.account)
#自己是当前使用的模型这个经理
#(显然这是错误的,因为你不是在一个模型
#实例中,但这是混乱来到我的地方
#我该怎么做?) 。

请忽略任何明显的语法错误。我在这里输入了这一切。



这里是我的想法: Django命名空间项目

解决方案

当涉及到Django时,有两个密切相关的问题。



一个是行级权限,其中用户/帐户需要特定权限查看表中的特定行(对象),而不是具有表级权限的常规Django身份验证框架。



项目您链接到的是尝试实现行权限的几个项目之一。 django-granular-permissions 是另一个和第三个(我最喜欢的和最活跃/维护的)是 django-authority



即将发布的Django 1.2将有钩子,使行级权限更容易实现,而 django-authority的作者将努力整合他的项目



第二个相关问题是多租户数据库,这是行权限的变体。在这个方案中,您可能会有一个单一公司的多个用户,例如,谁都可以访问该公司的数据,但不能访问其他公司(租户)。



我不要以为这是你正在寻找的,但你可能会使用一些相同的技术。请参阅如何强制Django中的帐户分离多租户django应用程序。两者都有很少的答案,但它们是一个出发点,同时也是针对Rails应用程序的多租户架构以及这篇文章



对于一个更具体的答案你的问题我认为你应该使用 django-authority 或者写一个自定义管理器并使用记录所有权筛选器,以验证您的查询不绕过自定义管理器。


To sum things up before I get into bad examples, et al: I'm trying to make an application where I don't have to write code in all my models to limit choices to the current logged in account (I'm not using Auth, or builtin features for the account or login).

ie, I don't want to have to do something like this:

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'))

My idea is to create an Account(models.Model) model with the following custom manager, and subclass it using multi-table inheritance with all of my models. It's giving me a huge brain ache though. Will I still need an account foreign key on each model? Can I access the parent class account for a certain model instance?

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?).

Please ignore any blaring syntax errors. I typed this whole thing in here.

Here's where I got the idea to do this: Django Namespace project

解决方案

There are two closely related problems when it comes to Django.

One is row level permissions where users/accounts need specific permission to view a specific row (object) in a table, as opposed to normal Django auth framework which has table level permissions.

The project you linked to is one of several projects trying to implement row permissions. django-granular-permissions is another and a third (my favorite and the most active/maintained) is django-authority.

The upcoming release of Django 1.2 will have hooks making row-level permissions easier to implement, and the author of django-authority will work on integrating his project.

The second related problem is something called multi-tenant database which is a variation on row permissions. In this scheme you might have multiple users from a single company, for example, who all have access to data for that company but not other companies (tenants).

I don't think this is what you're looking for but you might be able to use some of the same techniques. See how to enforce account separation in Django and multi-tenant django applications. Both have really sparse answers but are a starting point as well as looking at multi-tenant architecture for Rails apps and this article.

As for a more specific answer to your question I think you should either use django-authority or write a custom manager and use the record ownership screener during development to verify your queries aren't bypassing the custom manager.

这篇关于Django:如何组织这个大模特/经理/设计混乱?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆