Source code for django_owm.forms

"""Forms for django_owm."""

from decimal import ROUND_HALF_UP
from decimal import Decimal
from decimal import DecimalException

from django import forms
from django.apps import apps
from django.forms.fields import DecimalField

from .app_settings import OWM_MODEL_MAPPINGS
from .validators import validate_latitude
from .validators import validate_longitude


[docs] def quantize_to_2_decimal_places(value: Decimal | str | None) -> Decimal | None: """Quantize a Decimal value to 2 decimal places.""" if value is not None: if isinstance(value, str): try: value = Decimal(value) except DecimalException: return value if isinstance(value, Decimal): return value.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP) raise ValueError("Value must be a Decimal or a string that can be converted to a Decimal.") return value
[docs] class TrimmedDecimalField(DecimalField): """Custom DecimalField that trims the value to 2 decimal places."""
[docs] def to_python(self, value): """Trim the value to 2 decimal places.""" value = super().to_python(value) if value is not None: return quantize_to_2_decimal_places(value) return value
[docs] class WeatherLocationForm(forms.ModelForm): """Form for creating or updating a Weather Location.""" latitude = TrimmedDecimalField( max_digits=5, decimal_places=2, required=True, label="Latitude", help_text="Enter the latitude of the location (e.g., 40.7128)", ) longitude = TrimmedDecimalField( max_digits=5, decimal_places=2, required=True, label="Longitude", help_text="Enter the longitude of the location (e.g., -74.0060)", ) class Meta: """Meta class for WeatherLocationForm.""" model = apps.get_model(OWM_MODEL_MAPPINGS.get("WeatherLocation")) fields = ["name", "latitude", "longitude"]
[docs] def __init__(self, *args, **kwargs): """Initialize the form.""" super().__init__(*args, **kwargs) self.fields["name"].required = False
[docs] def clean_latitude(self): """Clean the input latitude value.""" latitude = self.cleaned_data.get("latitude") # Validate the latitude value is a Decimal within the valid range validate_latitude(latitude) return latitude
[docs] def clean_longitude(self): """Clean the input longitude value.""" longitude = self.cleaned_data.get("longitude") # Validate the longitude value is a Decimal within the valid range validate_longitude(longitude) return longitude