surenkov / django-pydantic-field

Django JSONField with Pydantic models as a Schema
https://pypi.org/project/django-pydantic-field/
Other
116 stars 12 forks source link

Posibility to omit a fields in the resulting JSON when it's unset? #62

Closed andreasnuesslein closed 6 months ago

andreasnuesslein commented 6 months ago

Hi @surenkov

I have another question regarding your pydantic field :)

I'm creating a BaseModel like so:

I18NSchema = create_model(
    "I18NField",
    __config__={"extra": Extra.forbid},
    **{
        lang[0]: (
            str,
            Field(default=None, description=f"Translation in {lang[0].upper()}"),
        )
        for lang in settings.LANGUAGES
    },
)

which basically results in a:

class I18NSchema(BaseModel):
    en: str = None
    fr: str = None
    ...

(I initially tried it with default="" too)

Is there a way to not have this in the database in the end:

{"af": null, "ar": null, "en": "hello", "es": null, "fr": "bonjour", "km": null, "lo": null, "mn": null, "pt": null, "ru": null, "th": null, "zh": null}
// respectively:
{"af": "", "ar": "", "en": "hello", "es": "", "fr": "bonjour", "km": "", "lo": "", "mn": "", "pt": "", "ru": "", "th": "", "zh": ""}

but only the keys that were actually set, i.e. in this case: {"en": "hello", "fr": "bonjour"}

thanks a bunch!

andreasnuesslein commented 6 months ago

(i'm guessing this discussion here is related to that: https://github.com/pydantic/pydantic/issues/1223 and I feel like there's no easy way)

surenkov commented 6 months ago

Hi @andreasnuesslein

I think you can pass exclude_defaults / exclude_unset / exclude_none=True, depending on your requirements to the field kwargs, e.g.:


class ConfigModel(models.Model):
    l18n_config = SchemaField(schema=I18NSchema, exclude_unset=True)
andreasnuesslein commented 6 months ago

!! perfect, thanks so much. totally solved exactly my situation. I feared I had to define "extras.Allow" and then dynamically parse extras etc. this is way better! :)