Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: surenkov/django-pydantic-field
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v0.3.10
Choose a base ref
...
head repository: surenkov/django-pydantic-field
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v0.3.12
Choose a head ref
  • 14 commits
  • 8 files changed
  • 2 contributors

Commits on Dec 17, 2024

  1. fix ValidationError on empty form rendering

    amyasnikov committed Dec 17, 2024
    Copy the full SHA
    2490961 View commit details
  2. fix for older django

    amyasnikov committed Dec 17, 2024
    Copy the full SHA
    e20abe4 View commit details

Commits on Dec 20, 2024

  1. Merge pull request #75 from amyasnikov/fix_68

    fix ValidationError on empty form rendering
    surenkov authored Dec 20, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    6afa93f View commit details
  2. Update python-publish.yml

    Switch to PyPI Trusted Publisher package distribution
    surenkov committed Dec 20, 2024

    Verified

    This commit was signed with the committer’s verified signature.
    surenkov Savva Surenkov
    Copy the full SHA
    1bd351e View commit details
  3. Drop Python 3.7 support

    surenkov committed Dec 20, 2024

    Verified

    This commit was signed with the committer’s verified signature.
    surenkov Savva Surenkov
    Copy the full SHA
    d0bbfe3 View commit details
  4. Declare Python 3.13 support

    surenkov committed Dec 20, 2024

    Verified

    This commit was signed with the committer’s verified signature.
    surenkov Savva Surenkov
    Copy the full SHA
    7c9b69d View commit details
  5. Merge pull request #76 from surenkov/drop-python-37

    Drop Python 3.7, declare 3.13 support
    surenkov authored Dec 20, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    0a0ba97 View commit details

Commits on Jan 14, 2025

  1. Verified

    This commit was signed with the committer’s verified signature.
    surenkov Savva Surenkov
    Copy the full SHA
    104246c View commit details
  2. Update ruff version

    surenkov committed Jan 14, 2025

    Verified

    This commit was signed with the committer’s verified signature.
    surenkov Savva Surenkov
    Copy the full SHA
    658b984 View commit details
  3. Verified

    This commit was signed with the committer’s verified signature.
    surenkov Savva Surenkov
    Copy the full SHA
    06b7e90 View commit details
  4. Small type improvements

    surenkov committed Jan 14, 2025

    Verified

    This commit was signed with the committer’s verified signature.
    surenkov Savva Surenkov
    Copy the full SHA
    518966e View commit details
  5. Merge pull request #79 from surenkov/feature/django-model-field-valid…

    …ation-error-with-plain-string-message
    
    Use plain exception strings when throwing `django.core.exceptions.ValidationError`
    surenkov authored Jan 14, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    48d42bc View commit details
  6. Merge pull request #78 from surenkov/feature/output-field-annotations…

    …-casting
    
    Type adaptation in `from_db_value`
    surenkov authored Jan 14, 2025

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    22a82e7 View commit details
  7. Bump to 0.3.12

    surenkov committed Jan 14, 2025

    Verified

    This commit was signed with the committer’s verified signature.
    surenkov Savva Surenkov
    Copy the full SHA
    fd899c7 View commit details
13 changes: 7 additions & 6 deletions .github/workflows/python-publish.yml
Original file line number Diff line number Diff line change
@@ -8,8 +8,12 @@ permissions:
contents: read

jobs:
publish:
pypi-publish:
name: upload release to PyPI
runs-on: ubuntu-latest
environment: release
permissions:
id-token: write
steps:
- uses: actions/checkout@v4
- name: Set up Python
@@ -22,8 +26,5 @@ jobs:
python -m pip install build
- name: Build package
run: python -m build
- name: Publish package
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
4 changes: 2 additions & 2 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
@@ -52,7 +52,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
pydantic-version: ["1.10.*", "2.*"]

services:
@@ -90,4 +90,4 @@ jobs:
- name: Install Pydantic ${{ matrix.pydantic-version }}
run: python -m pip install "pydantic==${{ matrix.pydantic-version }}"
- name: Test package
run: pytest
run: pytest
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ repos:
- id: check-hooks-apply
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.4.3
rev: v0.9.1
hooks:
# Run the linter.
- id: ruff
@@ -17,4 +17,4 @@ repos:
# Run the formatter.
- id: ruff-format
files: "^django_pydantic_field/"
exclude: ^.*\b(\.pytest_cache|\.venv|venv).*\b.*$
exclude: ^.*\b(\.pytest_cache|\.venv|venv).*\b.*$
2 changes: 1 addition & 1 deletion django_pydantic_field/v1/fields.py
Original file line number Diff line number Diff line change
@@ -81,7 +81,7 @@ def to_python(self, value) -> "base.SchemaT":
assert self.decoder is not None
return self.decoder().decode(value)
except pydantic.ValidationError as e:
raise django_exceptions.ValidationError(e.errors())
raise django_exceptions.ValidationError(str(e)) from e

def get_prep_value(self, value):
if not self._is_prepared_schema:
22 changes: 17 additions & 5 deletions django_pydantic_field/v2/fields.py
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@
from django.core.serializers.json import DjangoJSONEncoder
from django.db.models.expressions import BaseExpression, Col, Value
from django.db.models.fields import NOT_PROVIDED
from django.db.models.fields.json import JSONField
from django.db.models.fields.json import JSONField, KeyTransform
from django.db.models.lookups import Transform
from django.db.models.query_utils import DeferredAttribute

@@ -170,8 +170,19 @@ def to_python(self, value: ty.Any):
try:
return self.adapter.validate_python(value)
except pydantic.ValidationError as exc:
error_params = {"errors": exc.errors(), "field": self}
raise exceptions.ValidationError(exc.json(), code="invalid", params=error_params) from exc
raise exceptions.ValidationError(str(exc), code="invalid") from exc

def from_db_value(self, value, expression, connection):
if value is None:
return value
# Some backends (SQLite at least) extract non-string values in their SQL datatypes.
if isinstance(expression, KeyTransform) and not isinstance(value, str):
return value

try:
return self.adapter.validate_json(value)
except ValueError:
return value

def get_prep_value(self, value: ty.Any):
value = self._prepare_raw_value(value)
@@ -189,9 +200,10 @@ def get_default(self) -> ty.Any:
return self.adapter.validate_python(default_value)
return default_value

def formfield(self, **kwargs):
def formfield(self, form_class=None, choices_form_class=None, **kwargs):
field_kwargs = dict(
form_class=forms.SchemaField,
form_class=form_class or forms.SchemaField,
choices_form_class=choices_form_class,
# Trying to resolve the schema before passing it to the formfield, since in Django < 4.0,
# formfield is unbound during form validation and is not able to resolve forward refs defined in the model.
schema=self.adapter.prepared_schema,
3 changes: 3 additions & 0 deletions django_pydantic_field/v2/forms.py
Original file line number Diff line number Diff line change
@@ -80,6 +80,9 @@ def to_python(self, value: ty.Any) -> ty.Any:
return value

def prepare_value(self, value):
if value is None:
return None

if isinstance(value, InvalidJSONInput):
return value

6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "django-pydantic-field"
version = "0.3.10"
version = "0.3.12"
description = "Django JSONField with Pydantic models as a Schema"
readme = "README.md"
license = { file = "LICENSE" }
@@ -32,15 +32,15 @@ classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
]

requires-python = ">=3.7"
requires-python = ">=3.8"
dependencies = [
"pydantic>=1.10,<3",
"django>=3.1,<6",
11 changes: 10 additions & 1 deletion tests/v2/test_forms.py
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@
from django.forms import Form, modelform_factory

from tests.conftest import InnerSchema
from tests.test_app.models import SampleForwardRefModel, SampleSchema
from tests.test_app.models import SampleForwardRefModel, SampleSchema, ExampleSchema

fields = pytest.importorskip("django_pydantic_field.v2.fields")
forms = pytest.importorskip("django_pydantic_field.v2.forms")
@@ -19,6 +19,10 @@ class SampleForm(Form):
field = forms.SchemaField(ty.ForwardRef("SampleSchema"))


class NoDefaultForm(Form):
field = forms.SchemaField(schema=ExampleSchema)


@pytest.mark.parametrize(
"raw_data, clean_data",
[
@@ -153,3 +157,8 @@ def test_annotated_acceptance():
field = forms.SchemaField(te.Annotated[InnerSchema, pydantic.Field(title="Inner Schema")])
value = InnerSchema.model_validate({"stub_str": "abc", "stub_list": ["1970-01-01"]})
assert field.prepare_value(value)


def test_form_render_without_default():
form = NoDefaultForm()
form.as_p()