Upgrade to Django 6 (#20) (#26)
Unit Tests / test (push) Successful in 3s

## Summary

Closes #20.

- Bump Django pin from `>=5.2,<6` to `>=6.0,<7` (resolved **6.0.7**) and refresh `uv.lock`
- Update `TimeInfoBase.save` for Django 6 keyword-only `Model.save`
- Pass `required_score` directly to `ReCaptchaV3` (removes django-recaptcha deprecation warning)
- Fix `Payments.date` fixed default → callable `timezone.now` (+ migration `0012`)

Reviewed against [Django 6.0 release notes](https://docs.djangoproject.com/en/6.0/releases/6.0/). `DEFAULT_AUTO_FIELD` already `BigAutoField`. No other removed APIs in use.

**Compat notes**
- `django-phonenumber-field` 8.4.0 advertises Django 6.0 support
- `django-recaptcha` 4.1.0 has no upper Django bound; classifiers still list through 5.2 only — smoke-tested via suite

## Test plan

- [x] `uv run python manage.py check` — clean
- [x] `uv run python manage.py test` — 30 passed
- [ ] CI unit tests green on this PR
- [ ] Smoke board pages, membership form, auth/sign-in, recaptcha after merge/deploy

Reviewed-on: #26
This commit was merged in pull request #26.
This commit is contained in:
2026-07-14 05:13:55 -07:00
parent c9ff71bce5
commit 862b13a666
5 changed files with 28 additions and 13 deletions
+1 -5
View File
@@ -19,11 +19,7 @@ class CaptchaForm(forms.Form):
captcha = ReCaptchaField(
public_key=settings.RECAPTCHA_PUBLIC_KEY,
private_key=settings.RECAPTCHA_PRIVATE_KEY,
widget=ReCaptchaV3(
attrs={
'required_score':0.85,
}
),
widget=ReCaptchaV3(required_score=0.85),
)
@@ -0,0 +1,19 @@
# Generated by Django 6.0.7 on 2026-07-14 12:13
import django.utils.timezone
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('schasite', '0011_alter_payments_date_communitymember_and_more'),
]
operations = [
migrations.AlterField(
model_name='payments',
name='date',
field=models.DateField(default=django.utils.timezone.now),
),
]
+3 -3
View File
@@ -12,13 +12,13 @@ class TimeInfoBase(models.Model):
class Meta:
abstract = True
def save(self, *args, **kwargs):
def save(self, **kwargs):
if not kwargs.pop("skip_last_modified", False) and not hasattr(self, "skip_last_modified"):
self.last_modified = timezone.now()
if kwargs.get("update_fields") is not None:
kwargs["update_fields"] = list({*kwargs["update_fields"], "last_modified"})
super().save(*args, **kwargs)
super().save(**kwargs)
# Create your models here.
class UsefulLinks(TimeInfoBase):
@@ -148,7 +148,7 @@ class MembershipServices(TimeInfoBase):
class Payments(TimeInfoBase):
date = models.DateField(default=timezone.now())
date = models.DateField(default=timezone.now)
status = models.CharField(default="Completed", max_length=256)
email = models.EmailField(blank=True, null=True)
person = models.ForeignKey(