Addresses PR feedback

This commit is contained in:
Jason Novinger 2025-05-16 10:02:38 -05:00
parent 18b7a3187a
commit b4e15b6730
6 changed files with 31 additions and 50 deletions

View File

@ -1,3 +1,5 @@
# Generated by Django 5.2.1 on 2025-05-16 14:42
from django.db import migrations, models from django.db import migrations, models
@ -11,11 +13,6 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='circuit', model_name='circuit',
name='_abs_distance', name='_abs_distance',
field=models.DecimalField(blank=True, decimal_places=4, max_digits=18, null=True), field=models.DecimalField(blank=True, decimal_places=4, max_digits=13, null=True),
),
migrations.AlterField(
model_name='circuit',
name='distance',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=16, null=True),
), ),
] ]

View File

@ -1,3 +1,4 @@
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -55,10 +56,10 @@ class WeightMixin(models.Model):
class DistanceMixin(models.Model): class DistanceMixin(models.Model):
distance = models.DecimalField( distance = models.DecimalField(
verbose_name=_('distance'), verbose_name=_('distance'),
max_digits=16, max_digits=8,
decimal_places=2, decimal_places=2,
blank=True, blank=True,
null=True null=True,
) )
distance_unit = models.CharField( distance_unit = models.CharField(
verbose_name=_('distance unit'), verbose_name=_('distance unit'),
@ -69,7 +70,7 @@ class DistanceMixin(models.Model):
) )
# Stores the normalized distance (in meters) for database ordering # Stores the normalized distance (in meters) for database ordering
_abs_distance = models.DecimalField( _abs_distance = models.DecimalField(
max_digits=18, max_digits=13,
decimal_places=4, decimal_places=4,
blank=True, blank=True,
null=True null=True

View File

@ -1,10 +1,10 @@
import time import time
from decimal import Decimal
from django import forms from django import forms
from django.core.validators import MaxValueValidator, MinValueValidator
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from utilities.conversion import to_meters
__all__ = ( __all__ = (
'CheckLastUpdatedMixin', 'CheckLastUpdatedMixin',
) )
@ -49,30 +49,10 @@ class CheckLastUpdatedMixin(forms.Form):
class DistanceValidationMixin(forms.Form): class DistanceValidationMixin(forms.Form):
def clean(self): distance = forms.DecimalField(
super().clean() required=False,
validators=[
distance = self.cleaned_data.get('distance', None) MinValueValidator(Decimal(0)),
unit = self.cleaned_data.get('distance_unit', None) MaxValueValidator(Decimal(100000)),
if distance and unit: ]
model_class = self._meta.model )
distance_field = model_class._meta.get_field('distance')
max_digits = distance_field.max_digits - distance_field.decimal_places
max_distance = 10 ** max_digits
abs_distance = to_meters(distance, unit)
if abs_distance > max_distance:
raise forms.ValidationError(_(
"{distance} {unit} ({abs_distance} m) exceeds the maximum allowed distance for "
"{model._meta.verbose_name} distance. Distance must normalize to no more than "
"{max_distance} meters.".format(
distance=distance,
unit=unit,
abs_distance=abs_distance,
model=model_class,
max_distance=max_distance
)
))
self.cleaned_data['_abs_distance'] = abs_distance

View File

@ -6,7 +6,7 @@
<h2 class="col-9 offset-3">{{ heading }}</h2> <h2 class="col-9 offset-3">{{ heading }}</h2>
</div> </div>
{% endif %} {% endif %}
{% for layout, title, items in rows %} {% for layout, title, items, has_errors in rows %}
{% if layout == 'field' %} {% if layout == 'field' %}
{# Single form field #} {# Single form field #}
@ -25,12 +25,17 @@
{% elif layout == 'inline' %} {% elif layout == 'inline' %}
{# Multiple form fields on the same line #} {# Multiple form fields on the same line #}
<div class="row mb-3"> <div class="row mb-3 {% if has_errors %} has-errors{% endif %}">
<label class="col col-3 col-form-label text-lg-end">{{ title|default:'' }}</label> <label class="col col-3 col-form-label text-lg-end">{{ title|default:'' }}</label>
{% for field in items %} {% for field in items %}
<div class="col mb-1"> <div class="col mb-1 {% if field.errors %} has-errors{% endif %}">
{{ field }} {{ field }}
<div class="form-text">{% trans field.label %}</div> <div class="form-text">{% trans field.label %}</div>
{% if field.errors %}
<div class="form-text text-danger">
{% for error in field.errors %}{{ error }}{% if not forloop.last %}<br />{% endif %}{% endfor %}
</div>
{% endif %}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -53,6 +53,7 @@ def render_fieldset(form, fieldset):
Render a group set of fields. Render a group set of fields.
""" """
rows = [] rows = []
for item in fieldset.items: for item in fieldset.items:
# Multiple fields side-by-side # Multiple fields side-by-side
@ -61,7 +62,7 @@ def render_fieldset(form, fieldset):
form[name] for name in item.fields if name in form.fields form[name] for name in item.fields if name in form.fields
] ]
rows.append( rows.append(
('inline', item.label, fields) ('inline', item.label, fields, any(f.errors for f in fields))
) )
# Tabbed groups of fields # Tabbed groups of fields
@ -78,7 +79,7 @@ def render_fieldset(form, fieldset):
if not any(tab['active'] for tab in tabs): if not any(tab['active'] for tab in tabs):
tabs[0]['active'] = True tabs[0]['active'] = True
rows.append( rows.append(
('tabs', None, tabs) ('tabs', None, tabs, False)
) )
elif type(item) is ObjectAttribute: elif type(item) is ObjectAttribute:
@ -95,7 +96,7 @@ def render_fieldset(form, fieldset):
if field.name in getattr(form, 'nullable_fields', []): if field.name in getattr(form, 'nullable_fields', []):
field._nullable = True field._nullable = True
rows.append( rows.append(
('field', None, [field]) ('field', None, [field], False)
) )
return { return {

View File

@ -1,3 +1,5 @@
# Generated by Django 5.2.1 on 2025-05-16 14:42
from django.db import migrations, models from django.db import migrations, models
@ -11,11 +13,6 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='wirelesslink', model_name='wirelesslink',
name='_abs_distance', name='_abs_distance',
field=models.DecimalField(blank=True, decimal_places=4, max_digits=18, null=True), field=models.DecimalField(blank=True, decimal_places=4, max_digits=13, null=True),
),
migrations.AlterField(
model_name='wirelesslink',
name='distance',
field=models.DecimalField(blank=True, decimal_places=2, max_digits=16, null=True),
), ),
] ]