diff --git a/ws/car_states.py b/ws/car_states.py new file mode 100644 index 00000000..df1789c5 --- /dev/null +++ b/ws/car_states.py @@ -0,0 +1,70 @@ +""" +Provide a *simple* enumeration of US states without third-party deps. + +We used to rely on `localflavor` for this, but given that plates are +the *only* use for this enum, it's easy/simple to just enumerate. +""" +from typing import Final + +US_STATES: Final[tuple[tuple[str, str], ...]] = ( + ('AL', 'Alabama'), + ('AK', 'Alaska'), + ('AZ', 'Arizona'), + ('AR', 'Arkansas'), + ('CA', 'California'), + ('CO', 'Colorado'), + ('CT', 'Connecticut'), + ('DE', 'Delaware'), + ('DC', 'District of Columbia'), + ('FL', 'Florida'), + ('GA', 'Georgia'), + ('HI', 'Hawaii'), + ('ID', 'Idaho'), + ('IL', 'Illinois'), + ('IN', 'Indiana'), + ('IA', 'Iowa'), + ('KS', 'Kansas'), + ('KY', 'Kentucky'), + ('LA', 'Louisiana'), + ('ME', 'Maine'), + ('MD', 'Maryland'), + ('MA', 'Massachusetts'), + ('MI', 'Michigan'), + ('MN', 'Minnesota'), + ('MS', 'Mississippi'), + ('MO', 'Missouri'), + ('MT', 'Montana'), + ('NE', 'Nebraska'), + ('NV', 'Nevada'), + ('NH', 'New Hampshire'), + ('NJ', 'New Jersey'), + ('NM', 'New Mexico'), + ('NY', 'New York'), + ('NC', 'North Carolina'), + ('ND', 'North Dakota'), + ('OH', 'Ohio'), + ('OK', 'Oklahoma'), + ('OR', 'Oregon'), + ('PA', 'Pennsylvania'), + ('RI', 'Rhode Island'), + ('SC', 'South Carolina'), + ('SD', 'South Dakota'), + ('TN', 'Tennessee'), + ('TX', 'Texas'), + ('UT', 'Utah'), + ('VT', 'Vermont'), + ('VA', 'Virginia'), + ('WA', 'Washington'), + ('WV', 'West Virginia'), + ('WI', 'Wisconsin'), + ('WY', 'Wyoming'), +) + + +CAR_STATE_CHOICES: Final[tuple[tuple[str, str], ...]] = ( + *US_STATES, + # License plates are *only* used for search & rescue + # So long as the plate number is correct, we needn't be more specific. + # In nine years, we've only seen one Canadian license plate requested. + ('XX', 'Other (Canada, Mexico, etc.)'), +) diff --git a/ws/forms.py b/ws/forms.py index 76a3cfc7..4850a2f2 100644 --- a/ws/forms.py +++ b/ws/forms.py @@ -4,7 +4,6 @@ from django import forms from django.core.exceptions import ValidationError from django.db.models.fields import TextField -from localflavor.us.us_states import US_STATES from mitoc_const import affiliations from ws import enums, models, widgets @@ -165,7 +164,6 @@ class Meta: model = models.Car fields = ['license_plate', 'state', 'make', 'model', 'year', 'color'] widgets = { - 'state': forms.Select(choices=US_STATES), 'year': forms.NumberInput( attrs={'min': model.year_min, 'max': model.year_max} ), diff --git a/ws/migrations/0056_car.py b/ws/migrations/0056_car.py new file mode 100644 index 00000000..e390634e --- /dev/null +++ b/ws/migrations/0056_car.py @@ -0,0 +1,85 @@ +# Generated by Django 3.2.21 on 2023-10-02 13:42 + +import django.core.validators +import django.db.models.manager +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('ws', '0055_discount_url_non_null'), + ] + + operations = [ + migrations.AlterField( + model_name='car', + name='state', + field=models.CharField( + choices=[ + ('AL', 'Alabama'), + ('AK', 'Alaska'), + ('AZ', 'Arizona'), + ('AR', 'Arkansas'), + ('CA', 'California'), + ('CO', 'Colorado'), + ('CT', 'Connecticut'), + ('DE', 'Delaware'), + ('DC', 'District of Columbia'), + ('FL', 'Florida'), + ('GA', 'Georgia'), + ('HI', 'Hawaii'), + ('ID', 'Idaho'), + ('IL', 'Illinois'), + ('IN', 'Indiana'), + ('IA', 'Iowa'), + ('KS', 'Kansas'), + ('KY', 'Kentucky'), + ('LA', 'Louisiana'), + ('ME', 'Maine'), + ('MD', 'Maryland'), + ('MA', 'Massachusetts'), + ('MI', 'Michigan'), + ('MN', 'Minnesota'), + ('MS', 'Mississippi'), + ('MO', 'Missouri'), + ('MT', 'Montana'), + ('NE', 'Nebraska'), + ('NV', 'Nevada'), + ('NH', 'New Hampshire'), + ('NJ', 'New Jersey'), + ('NM', 'New Mexico'), + ('NY', 'New York'), + ('NC', 'North Carolina'), + ('ND', 'North Dakota'), + ('OH', 'Ohio'), + ('OK', 'Oklahoma'), + ('OR', 'Oregon'), + ('PA', 'Pennsylvania'), + ('RI', 'Rhode Island'), + ('SC', 'South Carolina'), + ('SD', 'South Dakota'), + ('TN', 'Tennessee'), + ('TX', 'Texas'), + ('UT', 'Utah'), + ('VT', 'Vermont'), + ('VA', 'Virginia'), + ('WA', 'Washington'), + ('WV', 'West Virginia'), + ('WI', 'Wisconsin'), + ('WY', 'Wyoming'), + ('XX', 'Other (Canada, Mexico, etc.)'), + ], + max_length=2, + ), + ), + migrations.AlterField( + model_name='car', + name='year', + field=models.PositiveIntegerField( + validators=[ + django.core.validators.MaxValueValidator(2025), + django.core.validators.MinValueValidator(1903), + ] + ), + ), + ] diff --git a/ws/models.py b/ws/models.py index 561a0614..e3871d55 100644 --- a/ws/models.py +++ b/ws/models.py @@ -21,7 +21,6 @@ from django.utils import timezone from django.utils.safestring import mark_safe from django.utils.text import format_lazy -from localflavor.us.models import USStateField from mitoc_const import affiliations from mitoc_const.membership import RENEWAL_ALLOWED_WITH_DAYS_LEFT from phonenumber_field.modelfields import PhoneNumberField @@ -29,6 +28,7 @@ import ws.utils.dates as date_utils from ws import enums +from ws.car_states import CAR_STATE_CHOICES from ws.utils.avatar import avatar_url alphanum = RegexValidator( @@ -63,7 +63,7 @@ class Car(models.Model): year_min, year_max = 1903, date_utils.local_now().year + 2 # Loosely validate - may wish to use international plates in the future license_plate = models.CharField(max_length=31, validators=[alphanum]) - state = USStateField() + state = models.CharField(max_length=2, choices=CAR_STATE_CHOICES) make = models.CharField(max_length=63) model = models.CharField(max_length=63) year = models.PositiveIntegerField(