Skip to main content

Extra django field validation.

Reason this release was yanked:

Bug with python2

Project description

django-extra-field-validation

PyPI PyPI - Python Version PyPI - Django Version Downloads

Build Status Codacy Badge Codacy Badge Total alerts Language grade: Python

Introduction

This package aims to provide tools needed to define custom field validation logic which can be used independently or with django forms, test cases, API implementation or any model operation that requires saving data to the database.

This can also be extended by defining table check constraints if needed but currently validation will only be handled at the model level.

Installation

django-extra-field-validation is distributed on PyPI as a universal wheel and is available on Linux/macOS and Windows and supports Python 2.7/3.5+ and PyPy.

pip install django-extra-field-validation

Usage

This provides model level validation which includes:

Require a single field in a collection

from django.db import models
from extra_validator import FieldValidationMixin


class TestModel(FieldValidationMixin, 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.
    ]

Example

In [1]: from decimal import Decimal

In [2]: from demo.models import TestModel

In [3]: TestModel.objects.create(amount=Decimal('2.50'), fixed_price=Decimal('3.00'))
---------------------------------------------------------------------------
ValueError                   Traceback (most recent call last)
...

ValueError: {'fixed_price': ValidationError([u'Please provide only one of: Amount, Fixed price, Percentage'])}

Require all fields

from django.db import models
from extra_validator import FieldValidationMixin


class TestModel(FieldValidationMixin, 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.

Example

In [1]: from decimal import Decimal

In [2]: from demo.models import TestModel

In [3]: TestModel.objects.create(fixed_price=Decimal('3.00'))
---------------------------------------------------------------------------
ValueError                   Traceback (most recent call last)
...

ValueError: {'amount': ValidationError([u'Please provide a value for: "amount".'])}

Optionally required fields

from django.db import models
from extra_validator import FieldValidationMixin


class TestModel(FieldValidationMixin, 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.
    ]

Example

In [1]: from decimal import Decimal

In [2]: from demo.models import TestModel

In [3]: first_obj = TestModel.objects.create(amount=Decimal('2.0'))

In [4]: second_obj = TestModel.objects.create(amount=Decimal('2.0'), fixed_price=Decimal('3.00'))

In [5]: third_obj = TestModel.objects.create(amount=Decimal('2.0'), fixed_price=Decimal('3.00'), percentage=Decimal('10.0'))
---------------------------------------------------------------------------
ValueError                   Traceback (most recent call last)
...

ValueError: {'percentage': ValidationError([u'Please provide only one of: Fixed price, Percentage'])}

Conditional required fields

from django.db import models
from django.conf import settings
from extra_validator import FieldValidationMixin


class TestModel(FieldValidationMixin, 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'],
        ),
    ]

Example

In [1]: from decimal import Decimal

in [2]: from django.contrib.auth import get_user_model

In [3]: from demo.models import TestModel

In [4]: user = get_user_model().objects.create(username='test', is_active=True)

In [5]: first_obj = TestModel.objects.create(user=user, amount=Decimal('2.0'))
---------------------------------------------------------------------------
ValueError                   Traceback (most recent call last)
...

ValueError: {u'percentage': ValidationError([u'Please provide a value for: "percentage"'])}

Conditional required optional fields

from django.db import models
from django.conf import settings
from extra_validator import FieldValidationMixin


class TestModel(FieldValidationMixin, 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'],
        ),
    ]

Example

In [1]: from decimal import Decimal

in [2]: from django.contrib.auth import get_user_model

In [3]: from demo.models import TestModel

In [4]: user = get_user_model().objects.create(username='test', is_active=True)

In [5]: first_obj = TestModel.objects.create(user=user)
---------------------------------------------------------------------------
ValueError                   Traceback (most recent call last)
...

ValueError: {'__all__': ValidationError([u'Please provide a valid value for any of the following fields: Fixed price, Percentage, Amount'])}

In [6]: second_obj = TestModel.objects.create(user=user, amount=Decimal('2'), fixed_price=Decimal('2'))
---------------------------------------------------------------------------
ValueError                   Traceback (most recent call last)
...

ValueError: {'__all__': ValidationError([u'Please provide only one of the following fields: Fixed price, Percentage, Amount'])}

Model Attributes

This is done using model attributes below.

#  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 = []

# Validates at least one, not both fields is provided if the condition is True.
CONDITIONAL_REQUIRED_TOGGLE_FIELDS = []

License

django-extra-field-validation is distributed under the terms of both

at your option.

TODO's

  • Support CONDITIONAL_NON_REQUIRED_TOGGLE_FIELDS
  • Support CONDITIONAL_NON_REQUIRED_FIELDS
  • Move to support class and function based validators that use the instance object this should enable cross field model validation.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

django-extra-field-validation-1.0.1.tar.gz (11.6 kB view details)

Uploaded Source

Built Distribution

File details

Details for the file django-extra-field-validation-1.0.1.tar.gz.

File metadata

  • Download URL: django-extra-field-validation-1.0.1.tar.gz
  • Upload date:
  • Size: 11.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.7.0 requests/2.24.0 setuptools/44.1.1 requests-toolbelt/0.9.1 tqdm/4.58.0 CPython/2.7.16

File hashes

Hashes for django-extra-field-validation-1.0.1.tar.gz
Algorithm Hash digest
SHA256 2c3e4de56a8ff8d62f6a29550bab72f517b07c92cddac037f0a4c753fc91b0d7
MD5 02452a99d44208b067d659ee579e895b
BLAKE2b-256 7521418d5acb0ee20ed02a920cd645315eccfec47f5658b4438f21183915d092

See more details on using hashes here.

File details

Details for the file django_extra_field_validation-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: django_extra_field_validation-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 15.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/1.15.0 pkginfo/1.7.0 requests/2.24.0 setuptools/44.1.1 requests-toolbelt/0.9.1 tqdm/4.58.0 CPython/2.7.16

File hashes

Hashes for django_extra_field_validation-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a80f4c9f72c54ce8d2195dc5b47a4f8e31e1313cc4e83fbe6489eb1f27847c75
MD5 f21ab37819259c5def6581e8575920d2
BLAKE2b-256 7cf4409bf81f0520c67c56e9660d56d521fb1129ee661e261a1e0982fb11e0b0

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page