From f1c4be8509b46410f634f1f56ebf90876d4eb966 Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Tue, 16 Dec 2025 15:18:44 -0500
Subject: [PATCH v1 1/3] Allow all users a contributor description

Previously only recognized contributors could add a description of their
contributions to Postgres. In order to support public contributor
profiles for all users (not just recognized contributors), contributors
must be able to add contributions.
---
 pgweb/account/views.py                        | 27 +++++++++----------
 .../0004_alter_contributor_ctype.py           | 24 +++++++++++++++++
 pgweb/contributors/models.py                  |  6 +++--
 templates/account/userprofileform.html        |  8 +++---
 4 files changed, 45 insertions(+), 20 deletions(-)
 create mode 100644 pgweb/contributors/migrations/0004_alter_contributor_ctype.py

diff --git a/pgweb/account/views.py b/pgweb/account/views.py
index 4f6cfa78..6900e04f 100644
--- a/pgweb/account/views.py
+++ b/pgweb/account/views.py
@@ -142,14 +142,14 @@ def profile(request):
     # accounts.
     can_change_email = (request.user.password != OAUTH_PASSWORD_STORE)
 
-    # We may have a contributor record - and we only show that part of the
-    # form if we have it for this user.
-    try:
-        contrib = Contributor.objects.get(user=request.user.pk)
-    except Contributor.DoesNotExist:
-        contrib = None
-
-    contribform = None
+    contrib, _ = Contributor.objects.get_or_create(
+        user=request.user,
+        defaults={
+            'firstname': request.user.first_name,
+            'lastname': request.user.last_name,
+            'email': request.user.email,
+        }
+    )
 
     secondaryaddresses = SecondaryEmail.objects.filter(user=request.user)
 
@@ -158,10 +158,9 @@ def profile(request):
         userform = UserForm(can_change_email, secondaryaddresses, data=request.POST, instance=request.user)
         profileform = UserProfileForm(data=request.POST, instance=profile)
         secondaryemailform = AddEmailForm(request.user, data=request.POST)
-        if contrib:
-            contribform = ContributorForm(data=request.POST, instance=contrib)
+        contribform = ContributorForm(data=request.POST, instance=contrib)
 
-        if userform.is_valid() and profileform.is_valid() and secondaryemailform.is_valid() and (not contrib or contribform.is_valid()):
+        if userform.is_valid() and profileform.is_valid() and secondaryemailform.is_valid() and contribform.is_valid():
             user = userform.save()
 
             # Email takes some magic special handling, since we only allow picking of existing secondary emails, but it's
@@ -179,8 +178,7 @@ def profile(request):
                 log.info("User {} changed primary email from {} to {}".format(user.username, oldemail, user.email))
 
             profileform.save()
-            if contrib:
-                contribform.save()
+            contribform.save()
             if secondaryemailform.cleaned_data.get('email1', ''):
                 sa = SecondaryEmail(user=request.user, email=secondaryemailform.cleaned_data['email1'], token=generate_random_token())
                 sa.save()
@@ -203,8 +201,7 @@ def profile(request):
         userform = UserForm(can_change_email, secondaryaddresses, instance=request.user)
         profileform = UserProfileForm(instance=profile)
         secondaryemailform = AddEmailForm(request.user)
-        if contrib:
-            contribform = ContributorForm(instance=contrib)
+        contribform = ContributorForm(instance=contrib)
 
     return render_pgweb(request, 'account', 'account/userprofileform.html', {
         'userform': userform,
diff --git a/pgweb/contributors/migrations/0004_alter_contributor_ctype.py b/pgweb/contributors/migrations/0004_alter_contributor_ctype.py
new file mode 100644
index 00000000..fdf15405
--- /dev/null
+++ b/pgweb/contributors/migrations/0004_alter_contributor_ctype.py
@@ -0,0 +1,24 @@
+# Generated by Django 5.2.8 on 2025-12-15 23:59
+
+import django.db.models.deletion
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('contributors', '0003_make_email_nullable'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='contributor',
+            name='ctype',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='contributors.contributortype', verbose_name='Contributor Type'),
+        ),
+        migrations.AlterField(
+            model_name='contributor',
+            name='contribution',
+            field=models.TextField(blank=True, help_text='Only displayed for Major Contributors', null=True),
+        ),
+    ]
diff --git a/pgweb/contributors/models.py b/pgweb/contributors/models.py
index 342cddb2..afecf2be 100644
--- a/pgweb/contributors/models.py
+++ b/pgweb/contributors/models.py
@@ -19,7 +19,9 @@ class ContributorType(models.Model):
 
 
 class Contributor(models.Model):
-    ctype = models.ForeignKey(ContributorType, on_delete=models.CASCADE, verbose_name='Contributor Type')
+    ctype = models.ForeignKey(ContributorType,
+                              on_delete=models.CASCADE,
+                              verbose_name='Contributor Type', null=True, blank=True)
     lastname = models.CharField(max_length=100, null=False, blank=False)
     firstname = models.CharField(max_length=100, null=False, blank=False)
     email = models.EmailField(null=False, blank=True)
@@ -27,7 +29,7 @@ class Contributor(models.Model):
     companyurl = models.URLField(max_length=100, null=True, blank=True, verbose_name='Company URL')
     location = models.CharField(max_length=100, null=True, blank=True)
     contribution = models.TextField(null=True, blank=True,
-                                    help_text='This description is currently used for major contributors only')
+                                    help_text='Only displayed for Major Contributors')
     user = models.ForeignKey(User, null=True, blank=True, on_delete=models.CASCADE)
 
     send_notification = True
diff --git a/templates/account/userprofileform.html b/templates/account/userprofileform.html
index 96ed2779..12d6ace4 100644
--- a/templates/account/userprofileform.html
+++ b/templates/account/userprofileform.html
@@ -94,9 +94,12 @@
       </div>
     {%endfor%}
 
-  {% if contribform %}
     <h2>Edit contributor information</h2>
-    <p>You can edit the information that's shown on the <a href="/community/contributors/" target="_blank" rel="noopener">contributors</a> page. Please be careful as your changes will take effect immediately!
+    <p>You can edit the information that is shown on your contributor profile.
+      If you are a recognized Major Contributor, this is what will be displayed
+      on the
+      <a href="/community/contributors/" target="_blank" rel="noopener">contributors</a>
+      page. Please be careful as your changes will take effect immediately!
     </p>
     {% for field in contribform %}
       <div class="form-group row">
@@ -116,7 +119,6 @@
         </div>
       </div>
     {% endfor %}
-  {% endif %}
 
   <div class="submit-row">
     <input class="btn btn-primary" type="submit" value="Save" />
-- 
2.51.2

