跳转到主要内容

额外的django模型验证。

项目描述

django-dynamic-model-validation

PyPI Build Status Codacy Badge Codacy Badge

PyPI - Python Version PyPI - Django Version Downloads

介绍

此软件包旨在提供定义自定义字段验证逻辑所需的工具,这些工具可以独立使用或与django表单、测试用例、API实现或任何需要将数据保存到数据库的模型操作一起使用。

如果需要,还可以通过定义表检查约束来扩展,但目前验证将在模型级别进行处理。

安装

django-dynamic-model-validation 以通用轮子形式发布在 PyPI 上,支持 Linux/macOS 和 Windows,并兼容 Python 2.7/3.5+ 和 PyPy。

pip install django-dynamic-model-validation

用法

该工具提供模型级别的验证,包括以下功能:

  • 条件字段验证
  • 跨字段验证
  • 必填字段验证
  • 可选字段验证

在集合中要求单个字段

from django.db import models
from dynamic_validator import ModelFieldRequiredMixin


class TestModel(ModelFieldRequiredMixin, models.Model):
    amount = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
    fixed_price = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True)
    percentage = models.DecimalField(max_digits=3, decimal_places=0, null=True, blank=True)

    REQUIRED_TOGGLE_FIELDS = [
        ['amount', 'fixed_price', 'percentage'],  # Require only one of the following fields.
    ]
python manage.py shell
...
>>> from decimal import Decimal
>>> from demo.models import TestModel
>>> TestModel.objects.create(amount=Decimal('2.50'), fixed_price=Decimal('3.00'))
...
ValueError: {'fixed_price': ValidationError([u'Please provide only one of: Amount, Fixed price, Percentage'])}

要求所有字段

from django.db import models
from dynamic_validator import ModelFieldRequiredMixin


class TestModel(ModelFieldRequiredMixin, models.Model):
    amount = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
    fixed_price = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True)
    percentage = models.DecimalField(max_digits=3, decimal_places=0, null=True, blank=True)

    REQUIRED_FIELDS = ['amount']  # Always requires an amount to create the instance.
python manage.py shell
...
>>> from decimal import Decimal
>>> from demo.models import TestModel
>>> TestModel.objects.create(fixed_price=Decimal('3.00'))
...
ValueError: {'amount': ValidationError([u'Please provide a value for: "amount".'])}

可选要求的字段

from django.db import models
from dynamic_validator import ModelFieldRequiredMixin


class TestModel(ModelFieldRequiredMixin, models.Model):
    amount = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
    fixed_price = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True)
    percentage = models.DecimalField(max_digits=3, decimal_places=0, null=True, blank=True)

    OPTIONAL_TOGGLE_FIELDS = [
        ['fixed_price', 'percentage']  # Optionally validates that only fixed price/percentage are provided when present.
    ]
python manage.py shell
...
>>> from decimal import Decimal
>>> from demo.models import TestModel
>>> first_obj = TestModel.objects.create(amount=Decimal('2.0'))
>>> second_obj = TestModel.objects.create(amount=Decimal('2.0'), fixed_price=Decimal('3.00'))
>>> third_obj = TestModel.objects.create(amount=Decimal('2.0'), fixed_price=Decimal('3.00'), percentage=Decimal('10.0'))
...
ValueError: {'percentage': ValidationError([u'Please provide only one of: Fixed price, Percentage'])}

条件必填字段

from django.db import models
from django.conf import settings
from dynamic_validator import ModelFieldRequiredMixin


class TestModel(ModelFieldRequiredMixin, models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)

    amount = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
    fixed_price = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True)
    percentage = models.DecimalField(max_digits=3, decimal_places=0, null=True, blank=True)

    CONDITIONAL_REQUIRED_FIELDS = [
        (
            lambda instance: instance.user.is_active, ['amount', 'percentage'],
        ),
    ]
python manage.py shell
...
>>> from decimal import Decimal
>>> from django.contrib.auth import get_user_model
>>> from demo.models import TestModel
>>> user = get_user_model().objects.create(username='test', is_active=True)
>>> first_obj = TestModel.objects.create(user=user, amount=Decimal('2.0'))
...
ValueError: {u'percentage': ValidationError([u'Please provide a value for: "percentage"'])}

条件必填可选字段

from django.db import models
from django.conf import settings
from dynamic_validator import ModelFieldRequiredMixin


class TestModel(ModelFieldRequiredMixin, models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)

    amount = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True)
    fixed_price = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True)
    percentage = models.DecimalField(max_digits=3, decimal_places=0, null=True, blank=True)

    CONDITIONAL_REQUIRED_TOGGLE_FIELDS = [
        (
            lambda instance: instance.user.is_active, ['fixed_price', 'percentage', 'amount'],
        ),
    ]
python manage.py shell
...
>>> from decimal import Decimal
>>> from django.contrib.auth import get_user_model
>>> from demo.models import TestModel
>>> user = get_user_model().objects.create(username='test', is_active=True)
>>> first_obj = TestModel.objects.create(user=user)
...
ValueError: {'__all__': ValidationError([u'Please provide a valid value for any of the following fields: Fixed price, Percentage, Amount'])}
...
>>>first_obj = TestModel.objects.create(user=user, amount=Decimal('2'), fixed_price=Decimal('2'))
...
ValueError: {'__all__': ValidationError([u'Please provide only one of the following fields: Fixed price, Percentage, Amount'])}
...

模型属性

这是通过以下模型属性实现的。

#  Using a list/iterable: [['a', 'b'], ['c', 'd']] which validates that a field from each item is provided.
REQUIRED_TOGGLE_FIELDS = []

# Using a list/iterable validates that all fields are provided.
REQUIRED_FIELDS = []

# Optional toggle fields list: [['a', 'b']] which runs the validation only when any of the fields are present.
OPTIONAL_TOGGLE_FIELDS = []

# Conditional field validation using a list of tuples the condition which could be boolean or a callable and the list/iterable of fields that are required if the condition evaluates to `True`.
# [(condition, [fields]), (condition, fields)]

# Using a callable CONDITIONAL_REQUIRED_FIELDS = [(lambda instance: instance.is_admin, ['a', 'd'])]
# Using a boolean CONDITIONAL_REQUIRED_TOGGLE_FIELDS = [(True, ['b', 'c']), (True, ['d', f])]
# asserts that either 'b' or 'c' is provided and either 'd' or 'f'.
# (Note: This can also be handled using REQUIRED_FIELDS/REQUIRED_TOGGLE_FIELDS)

# Validates that all fields are present if the condition is True
CONDITIONAL_REQUIRED_FIELDS = []
# Validated at least one not both fields are provided if the condition is True.
CONDITIONAL_REQUIRED_TOGGLE_FIELDS = []

许可协议

django-dynamic-model-validation 采用 MIT 许可证和 Apache 许可证 v2.0 的条款进行分发,您可以选择其中一种。

任选其一。

待办事项

  • 迁移到支持基于类和函数的验证器,这些验证器使用实例对象,这应该能够实现跨字段模型验证。

项目详情


下载文件

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

源代码分发

django-dynamic-model-validation-1.0.0.tar.gz (11.4 kB 查看哈希值)

上传时间 源代码

构建分发

django_dynamic_model_validation-1.0.0-py3-none-any.whl (15.7 kB 查看哈希值)

上传时间 Python 3

由以下机构支持

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