Skip to content

Commit 34503e6

Browse files
authored
Add more info to captured email table and allow csv upload (#1998)
1 parent 69a652d commit 34503e6

File tree

6 files changed

+124
-3
lines changed

6 files changed

+124
-3
lines changed

config/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"health_check.db",
7676
"health_check.contrib.celery",
7777
"imagekit",
78+
"import_export",
7879
"django_countries",
7980
# Allows authentication for Mailman
8081
"oauth2_provider",

marketing/admin.py

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,53 @@
11
from django.contrib import admin
2+
from import_export.admin import ImportExportModelAdmin
3+
from import_export import resources, fields
24

35
from marketing.models import CapturedEmail
46

57

8+
class CapturedEmailResource(resources.ModelResource):
9+
email = fields.Field(column_name="Email", attribute="email")
10+
first_name = fields.Field(column_name="Name (First Name)", attribute="first_name")
11+
last_name = fields.Field(column_name="Name (Last Name)", attribute="last_name")
12+
mi = fields.Field(column_name="Name (M.I.)", attribute="mi")
13+
title = fields.Field(column_name="Title", attribute="title")
14+
company = fields.Field(column_name="Company", attribute="company")
15+
address_city = fields.Field(column_name="Address (City)", attribute="address_city")
16+
address_state = fields.Field(
17+
column_name="Address (State)", attribute="address_state"
18+
)
19+
address_country = fields.Field(
20+
column_name="Address (Country)", attribute="address_country"
21+
)
22+
23+
class Meta:
24+
model = CapturedEmail
25+
# Use email as the natural key so re-imports update instead of duplicating
26+
import_id_fields = ["email"]
27+
skip_unchanged = True
28+
report_skipped = True
29+
fields = (
30+
"email",
31+
"first_name",
32+
"last_name",
33+
"mi",
34+
"title",
35+
"company",
36+
"address_city",
37+
"address_state",
38+
"address_country",
39+
)
40+
41+
642
@admin.register(CapturedEmail)
7-
class CapturedEmailAdmin(admin.ModelAdmin):
8-
model = CapturedEmail
9-
list_display = ("email", "referrer", "page")
43+
class CapturedEmailAdmin(ImportExportModelAdmin):
44+
resource_class = CapturedEmailResource
45+
list_display = (
46+
"email",
47+
"first_name",
48+
"last_name",
49+
"company",
50+
"address_city",
51+
"address_state",
52+
"address_country",
53+
)
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Generated by Django 5.2.7 on 2025-11-04 22:23
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("marketing", "0002_detailpage_outreachhomepage_programpage_and_more"),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name="capturedemail",
15+
name="address_city",
16+
field=models.CharField(blank=True, default=""),
17+
),
18+
migrations.AddField(
19+
model_name="capturedemail",
20+
name="address_country",
21+
field=models.CharField(blank=True, default=""),
22+
),
23+
migrations.AddField(
24+
model_name="capturedemail",
25+
name="address_state",
26+
field=models.CharField(blank=True, default=""),
27+
),
28+
migrations.AddField(
29+
model_name="capturedemail",
30+
name="company",
31+
field=models.CharField(blank=True, default=""),
32+
),
33+
migrations.AddField(
34+
model_name="capturedemail",
35+
name="first_name",
36+
field=models.CharField(blank=True, default=""),
37+
),
38+
migrations.AddField(
39+
model_name="capturedemail",
40+
name="last_name",
41+
field=models.CharField(blank=True, default=""),
42+
),
43+
migrations.AddField(
44+
model_name="capturedemail",
45+
name="mi",
46+
field=models.CharField(blank=True, default="", verbose_name="M.I."),
47+
),
48+
migrations.AddField(
49+
model_name="capturedemail",
50+
name="opted_out",
51+
field=models.BooleanField(default=False),
52+
),
53+
migrations.AddField(
54+
model_name="capturedemail",
55+
name="title",
56+
field=models.CharField(blank=True, default=""),
57+
),
58+
]

marketing/models.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@
2626

2727
class CapturedEmail(models.Model):
2828
email = models.EmailField()
29+
first_name = models.CharField(blank=True, default="")
30+
last_name = models.CharField(blank=True, default="")
31+
mi = models.CharField(blank=True, default="", verbose_name="M.I.")
32+
title = models.CharField(blank=True, default="")
33+
company = models.CharField(blank=True, default="")
34+
address_city = models.CharField(blank=True, default="")
35+
address_state = models.CharField(blank=True, default="")
36+
address_country = models.CharField(blank=True, default="")
37+
opted_out = models.BooleanField(default=False)
38+
2939
referrer = models.CharField(blank=True, default="")
3040
page = models.ForeignKey(
3141
Page,

requirements.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ django-db-geventpool
1010
django-extensions
1111
django-health-check
1212
django-imagekit
13+
django-import-export
1314
django-oauth-toolkit
1415
django-redis
1516
django-upgrade

requirements.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ cycler==0.12.1
109109
# via matplotlib
110110
decorator==5.2.1
111111
# via ipython
112+
diff-match-patch==20241021
113+
# via django-import-export
112114
defusedxml==0.7.1
113115
# via willow
114116
distlib==0.4.0
@@ -132,6 +134,7 @@ django==5.2.8
132134
# django-filter
133135
# django-haystack
134136
# django-health-check
137+
# django-import-export
135138
# django-js-asset
136139
# django-modelcluster
137140
# django-oauth-toolkit
@@ -177,6 +180,8 @@ django-health-check==3.20.0
177180
# via -r ./requirements.in
178181
django-imagekit==6.0.0
179182
# via -r ./requirements.in
183+
django-import-export==4.3.13
184+
# via -r ./requirements.in
180185
django-js-asset==3.1.2
181186
# via django-mptt
182187
django-modelcluster==6.4
@@ -483,6 +488,8 @@ stack-data==0.6.3
483488
# via ipython
484489
structlog==25.5.0
485490
# via -r ./requirements.in
491+
tablib==3.9.0
492+
# via django-import-export
486493
tabulate==0.9.0
487494
# via interrogate
488495
telepath==0.3.1

0 commit comments

Comments
 (0)