跳转到主要内容

允许ORM结构在属性访问时进行密封,以防止它们执行查询。

项目描述

Seal
Build Status Coverage status

Django应用程序,提供查询集密封功能,强制使用only()/defer()select_related()/prefetch_related()

安装

pip install django-seal

使用

# models.py
from django.db import models
from seal.models import SealableModel

class Location(SealableModel):
    latitude = models.FloatField()
    longitude = models.FloatField()

class SeaLion(SealableModel):
    height = models.PositiveIntegerField()
    weight = models.PositiveIntegerField()
    location = models.ForeignKey(Location, models.CASCADE, null=True)
    previous_locations = models.ManyToManyField(Location, related_name='previous_visitors')

默认情况下,在密封对象属性访问时将引发UnsealedAttributeAccess警告

>>> location = Location.objects.create(latitude=51.585474, longitude=156.634331)
>>> sealion = SeaLion.objects.create(height=1, weight=100, location=location)
>>> sealion.previous_locations.add(location)
>>> SeaLion.objects.only('height').seal().get().weight
UnsealedAttributeAccess:: Attempt to fetch deferred field "weight" on sealed <SeaLion instance>.
>>> SeaLion.objects.seal().get().location
UnsealedAttributeAccess: Attempt to fetch related field "location" on sealed <SeaLion instance>.
>>> SeaLion.objects.seal().get().previous_locations.all()
UnsealedAttributeAccess: Attempt to fetch many-to-many field "previous_locations" on sealed <SeaLion instance>.

您可以通过过滤警告将警告提升为异常。这在例如运行测试套件时断言没有执行未密封的属性访问非常有用。

>>> import warnings
>>> from seal.exceptions import UnsealedAttributeAccess
>>> warnings.filterwarnings('error', category=UnsealedAttributeAccess)
>>> SeaLion.objects.only('height').seal().get().weight
Traceback (most recent call last)
...
UnsealedAttributeAccess:: Attempt to fetch deferred field "weight" on sealed <SeaLion instance>.
>>> SeaLion.objects.seal().get().location
Traceback (most recent call last)
...
UnsealedAttributeAccess: Attempt to fetch related field "location" on sealed <SeaLion instance>.
>>> SeaLion.objects.seal().get().previous_locations.all()
Traceback (most recent call last)
...
UnsealedAttributeAccess: Attempt to fetch many-to-many field "previous_locations" on sealed <SeaLion instance>.

或者,您可以配置日志记录以捕获警告,将未密封的属性访问记录到py.warnings记录器,这是一种在不停机的情况下从生产日志中识别和解决未密封属性访问的好方法。

>>> import logging
>>> logging.captureWarnings(True)

可密封的管理器也可以在模型定义时自动密封,以避免必须系统地调用seal(),通过将seal=True传递给SealableModel子类、SealableManagerSealableQuerySet.as_manager

from django.db import models
from seal.models import SealableManager, SealableModel, SealableQuerySet

class Location(SealableModel, seal=True):
    latitude = models.FloatField()
    longitude = models.FloatField()

class SeaLion(SealableModel):
    height = models.PositiveIntegerField()
    weight = models.PositiveIntegerField()
    location = models.ForeignKey(Location, models.CASCADE, null=True)
    previous_locations = models.ManyToManyField(Location, related_name='previous_visitors')

    objects = SealableManager(seal=True)
    others = SealableQuerySet.as_manager(seal=True)

开发

修改您的更改,然后通过tox运行测试

tox

项目详情


下载文件

下载适用于您的平台文件。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分发

django_seal-1.6.3.tar.gz (13.0 kB 查看哈希)

上传时间

构建分发

django_seal-1.6.3-py2.py3-none-any.whl (9.3 kB 查看哈希)

上传时间 Python 2 Python 3

由以下机构支持

AWS AWS 云计算和安全赞助商 Datadog Datadog 监控 Fastly Fastly CDN Google Google 下载分析 Microsoft Microsoft PSF 赞助商 Pingdom Pingdom 监控 Sentry Sentry 错误记录 StatusPage StatusPage 状态页