限制模型只能访问具有特定条件的行?

时间:2013-04-09 10:58:56

标签: django django-models

我想使用Django模型来访问数据库行的子集。与许多遗留数据库一起使用,如果可能的话,我宁愿不为数据库创建视图。

简而言之,我想告诉我的模型,字段foo应始终具有值bar。这应该跨越表的任何CRUD操作,以便新创建的行也具有foo = bar。对于我想要实现的目标,是否有简单的Django方式?

更新:我想确保此模型不会在foo!= bar的表格中写入任何内容。它必须能够只读取,修改或删除foo = bar的行。

1 个答案:

答案 0 :(得分:1)

对于新创建的项目,您可以在模型定义中设置default

class MyModel(models.Model):
    # a lot of fields
    foo = models.CharField(max_length=10, default='bar')

    # Set the manager
    objects = BarManager()

    def save(self, force_insert=False, force_update=False, using=None):
        self.foo = 'bar'
        super(MyModel, self).save(force_insert, force_update, using)

要实现MyModel.objects.all()只应返回foo=bar行,您应该实现your custom manager。您可以重新定义get_query_set方法以添加过滤。

class BarManager(models.Manager):
    use_for_related_fields = True

    def get_query_set(self):
        return super(BarManager, self).get_query_set().filter(foo='bar')

@tuomassalo评论

后更新

1)自定义管理器会影响对MyModel.objects.get(id=42)的所有来电,因为此调用仅代理对.get_query_set().get(id=42)的调用。要实现此目的,您必须将Manager设置为模型的默认管理器(将其分配给objects变量)。

要将此管理器用于相关查找(例如another_model_instance.my_model_set.get(id=42)),您需要在use_for_related_fields = True上设置BarManager。请参阅文档中的Controlling automatic Manager types

2)如果您想强制执行foo=bar,那么default值对您来说是不够的。您可以使用pre_save信号或覆盖模型上的save方法。不要忘记调用原始保存方法。

我更新了上面的MyModel示例。