Skip to content

Commit a20b7c3

Browse files
committed
update django to 3.2 and python to 3.10
1 parent d77200c commit a20b7c3

File tree

9 files changed

+144
-42
lines changed

9 files changed

+144
-42
lines changed

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
FROM python:3.9.23-slim
1+
FROM python:3.10.18-slim
2+
# python 3.10 end of life October 2026, need to refactor code to Django 5
23

34
WORKDIR /app
45

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ python manage.py test
2828
python manage.py runserver 0:8000 --settings=representable.settings.dev
2929
```
3030

31+
###### Tips
32+
33+
- If you update .env, you must run `source .env` to refresh it in your container.
34+
3135
### General Issue Reporting
3236
For bug reports and general feature requests, please open a [Github issue](https://github.com/Representable/representable/issues/new/choose). We welcome all feedback and suggestions!
3337

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Generated by Django 3.2.25 on 2025-10-07 20:35
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('main', '0100_auto_20211213_0809'),
10+
]
11+
12+
operations = [
13+
migrations.AlterField(
14+
model_name='address',
15+
name='id',
16+
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
17+
),
18+
migrations.AlterField(
19+
model_name='allowlist',
20+
name='id',
21+
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
22+
),
23+
migrations.AlterField(
24+
model_name='blockgroup',
25+
name='id',
26+
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
27+
),
28+
migrations.AlterField(
29+
model_name='censusblock',
30+
name='id',
31+
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
32+
),
33+
migrations.AlterField(
34+
model_name='communityentry',
35+
name='id',
36+
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
37+
),
38+
migrations.AlterField(
39+
model_name='drivetoken',
40+
name='id',
41+
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
42+
),
43+
migrations.AlterField(
44+
model_name='membership',
45+
name='id',
46+
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
47+
),
48+
migrations.AlterField(
49+
model_name='organization',
50+
name='id',
51+
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
52+
),
53+
migrations.AlterField(
54+
model_name='report',
55+
name='id',
56+
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
57+
),
58+
migrations.AlterField(
59+
model_name='signature',
60+
name='id',
61+
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
62+
),
63+
migrations.AlterField(
64+
model_name='state',
65+
name='id',
66+
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
67+
),
68+
migrations.AlterField(
69+
model_name='user',
70+
name='first_name',
71+
field=models.CharField(blank=True, max_length=150, verbose_name='first name'),
72+
),
73+
migrations.AlterField(
74+
model_name='user',
75+
name='id',
76+
field=models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'),
77+
),
78+
]

main/templates/account/signup.html

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@
77
{% load i18n %}
88

99
<div class="auth-wrap col-sm-9 col-md-7 col-lg-5 mx-auto">
10+
<div class="row equal auth-form">
11+
<div class="col-lg-1 col-md-1 col-xs-12 text-center">
12+
<i class="fas fa-lock m-1 text-primary"></i>
13+
</div>
14+
<div class="col-lg-10 col-md-9">
15+
<p class="text-left align-text-bottom privacy-note">{% trans "Making an account helps us protect legitimate submissions." %}</p>
16+
</div>
17+
</div>
1018
<a href="{% provider_login_url 'google' %}">
1119
<button
1220
style="gap: 1rem;"
@@ -15,9 +23,9 @@
1523
alt="Google icon logo" />{% trans "Sign up with Google" %}
1624
</button>
1725
</a>
18-
<h3 class="my-2">OR</h3>
26+
<!-- <h3 class="my-2">OR</h3> -->
1927
<form id="signup-form" class="signup auth-form" method="post" action="{% url 'account_signup' %}">
20-
<fieldset disabled="disabled" title="Disabled due to email server issue. Please use google to sign up for now.">
28+
<!-- <fieldset disabled="disabled" title="Disabled due to email server issue. Please use google to sign up for now.">
2129
{% if redirect_field_value %}
2230
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
2331
{% endif %}
@@ -42,17 +50,9 @@ <h3 class="my-2">OR</h3>
4250
{% endfor %}
4351
</div>
4452
45-
<div class="row equal">
46-
<div class="col-lg-1 col-md-1 col-xs-12 text-center">
47-
<i class="fas fa-lock m-1 text-primary"></i>
48-
</div>
49-
<div class="col-lg-10 col-md-9">
50-
<p class="text-left align-text-bottom privacy-note">{% trans "Making an account helps us protect legitimate submissions." %}</p>
51-
</div>
52-
</div>
5353
<div class="auth-btn-wrap">
5454
<button class="btn btn-lg btn-primary text-uppercase auth-btn" type="submit">{% trans "Sign Up" %}</button>
55-
</div>
55+
</div> -->
5656

5757
<a class="auth-link to-auth-link" href="#login-form">{% trans "Already have an account? Log in."%}</a>
5858
</fieldset>

main/test_entry.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,22 @@
1313
from django.contrib.gis.db.models import Union
1414
from django.contrib.gis.db import models
1515
from django.contrib.gis.geos import GEOSGeometry
16-
16+
from main.models import State
1717

1818
class EntryTest(TestCase):
1919
def setUp(self):
2020
# Create a fake user.
2121
self.client = Client()
2222
print("Testing Create User")
2323

24+
State.objects.create(
25+
name='Michigan',
26+
abbr='MI',
27+
content_news='<p>Test news content</p>',
28+
content_criteria='<p>Test criteria content</p>',
29+
content_coi='<p>Test COI content</p>'
30+
)
31+
2432
self.user = get_user_model().objects.create_user(
2533
"johndoe", "john@doe.com", "johndoe"
2634
)

main/tests.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from main.forms import CommunityForm
2222
from main.views import EntryView
2323
from django.contrib.auth import get_user_model
24-
24+
from main.models import State
2525

2626
class UserTest(TestCase):
2727
"""
@@ -34,6 +34,13 @@ def setUp(self):
3434
"""
3535
self.client = Client()
3636

37+
State.objects.create(
38+
name='Michigan',
39+
abbr='MI',
40+
content_news='<p>Test news content</p>',
41+
content_criteria='<p>Test criteria content</p>',
42+
)
43+
3744
def testSimpleGet(self):
3845
"""
3946
Test get main page, map page, and entry page.
@@ -44,10 +51,9 @@ def testSimpleGet(self):
4451
# Check that response is 200 OK.
4552
self.assertEqual(response.status_code, 200)
4653

47-
# Check map page.
48-
print("Testing Map Page")
49-
response = self.client.get("/map")
50-
# Check that response is 301 Redirect. (why?)
54+
# Check review page.
55+
print("Testing Review Page")
56+
response = self.client.get("/review")
5157
self.assertEqual(response.status_code, 301)
5258

5359
# Check entry page.

main/views/main.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ def dispatch(self, request, *args, **kwargs):
171171
# View template for both the signing up and signing in
172172
class RepresentableLoginView(LoginView):
173173
template_name = "account/signup_login.html"
174-
login_form = RepresentableLoginForm()
175-
signup_form = RepresentableSignupForm()
174+
login_form = RepresentableLoginForm
175+
signup_form = RepresentableSignupForm
176176
request = None
177177

178178
def dispatch(self, request, *args, **kwargs):
@@ -207,8 +207,8 @@ def get_context_data(self, **kwargs):
207207

208208
class RepresentableSignupView(SignupView):
209209
template_name = "account/signup_login.html"
210-
login_form = RepresentableLoginForm()
211-
signup_form = RepresentableSignupForm()
210+
login_form = RepresentableLoginForm
211+
signup_form = RepresentableSignupForm
212212
request = None
213213

214214
def dispatch(self, request, *args, **kwargs):

representable/settings/base.py

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
import django_heroku
3333
import os
3434

35+
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
36+
3537
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
3638
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
3739

@@ -86,9 +88,10 @@
8688
# https://docs.allauth.org/en/dev/socialaccount/providers/google.html
8789
'google': {
8890
'VERIFIED_EMAIL': True,
91+
'EMAIL_AUTHENTICATION': True,
8992
'APP': {
90-
'client_id': os.getenv("GOOGLE_OAUTH_CLIENT_ID"),
91-
'secret': os.getenv("GOOGLE_OAUTH_SECRET"),
93+
'client_id': os.environ["GOOGLE_OAUTH_CLIENT_ID"],
94+
'secret': os.environ["GOOGLE_OAUTH_SECRET"],
9295
'key': ''
9396
},
9497
'SCOPE': [
@@ -101,9 +104,22 @@
101104
}
102105
}
103106

104-
SOCIALACCOUNT_LOGIN_ON_GET = True
107+
SOCIALACCOUNT_AUTO_SIGNUP = True
108+
SOCIALACCOUNT_EMAIL_AUTHENTICATION_AUTO_CONNECT = True
109+
110+
# Can Log In With Either Email or Username
111+
ACCOUNT_AUTHENTICATION_METHOD = "email"
112+
ACCOUNT_EMAIL_REQUIRED = True
113+
ACCOUNT_USERNAME_REQUIRED = False
114+
115+
# Always remember login (hide the Remember me? checkbox)
105116
ACCOUNT_SESSION_REMEMBER = True
106117

118+
# Send an email via mailgun
119+
DEFAULT_FROM_EMAIL = "no-reply@representable.org"
120+
ACCOUNT_EMAIL_VERIFICATION = "optional"
121+
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 7
122+
107123

108124
SITE_ID = 1
109125
# SOCIALAPP_ID = 1
@@ -122,6 +138,7 @@
122138
"django.contrib.auth.middleware.AuthenticationMiddleware",
123139
"django.contrib.messages.middleware.MessageMiddleware",
124140
"django.middleware.clickjacking.XFrameOptionsMiddleware",
141+
"allauth.account.middleware.AccountMiddleware"
125142
]
126143

127144
ROOT_URLCONF = "representable.urls"
@@ -266,18 +283,6 @@
266283
"ENGINE"
267284
] = "django.contrib.gis.db.backends.spatialite"
268285

269-
# Can Log In With Either Email or Username
270-
ACCOUNT_AUTHENTICATION_METHOD = "email"
271-
272-
ACCOUNT_EMAIL_REQUIRED = True
273-
ACCOUNT_USERNAME_REQUIRED = False
274-
DEFAULT_FROM_EMAIL = "no-reply@representable.org"
275-
276-
ACCOUNT_EMAIL_VERIFICATION = "optional"
277-
278-
ACCOUNT_EMAIL_CONFIRMATION_EXPIRE_DAYS = 7
279-
280-
281286
# Recaptcha form submit check (not the same as verification)
282287
if "TRAVIS" in os.environ:
283288
CHECK_CAPTCHA_SUBMIT = False

requirements.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ botocore==1.19.22
66
chardet==3.0.4
77
Click==7.0
88
dj-database-url==0.5.0
9-
Django==2.2.24
10-
django-allauth==0.51.0
9+
Django==3.2.25
10+
django-allauth==0.61.0
1111
django-appconf==1.0.3
1212
django-bmemcached==0.2.4
1313
django-ckeditor==5.9.0
@@ -16,7 +16,7 @@ django-extensions==3.0.9
1616
django-heroku==0.3.1
1717
django-import-export==2.2.0
1818
django-js-asset==1.2.2
19-
django-leaflet==0.24.0
19+
django-leaflet==0.28.3
2020
django-phone-field==1.8.0
2121
django-redis==4.10.0
2222
django-redis-cache==2.0.0
@@ -26,8 +26,8 @@ django-widget-tweaks==1.4.3
2626
et-xmlfile==1.0.1
2727
Faker==1.0.5
2828
future==0.18.2
29-
geojson==2.4.1
30-
geojson-rewind==0.2.0
29+
geojson==3.2.0
30+
geojson-rewind==1.1.0
3131
gunicorn==19.9.0
3232
google-api-core==1.26.3
3333
google-api-python-client==2.4.0

0 commit comments

Comments
 (0)