Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add field to profile for user to specify type #421

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions backend/clubs/migrations/0078_profile_affiliation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Generated by Django 3.1.6 on 2021-04-11 17:46

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("clubs", "0077_auto_20210219_2014"),
]

operations = [
migrations.AddField(
model_name="profile",
name="affiliation",
field=models.PositiveSmallIntegerField(
choices=[
(0, "Undergraduate"),
(1, "Masters"),
(2, "Professional"),
(3, "Doctoral"),
(4, "Staff"),
],
default=0,
),
),
]
47 changes: 47 additions & 0 deletions backend/clubs/models.py
Original file line number Diff line number Diff line change
@@ -1415,9 +1415,26 @@ class Profile(models.Model):
Additional information attached to a user account.
"""

UNDERGRADUATE = 0
MASTERS = 1
PROFESSIONAL = 2
PHD = 3
STAFF = 4

AFFILIATION_CHOICES = (
(UNDERGRADUATE, "Undergraduate"),
(MASTERS, "Masters"),
(PROFESSIONAL, "Professional"),
(PHD, "Doctoral"),
(STAFF, "Staff"),
)

user = models.OneToOneField(
get_user_model(), on_delete=models.CASCADE, primary_key=True
)
affiliation = models.PositiveSmallIntegerField(
choices=AFFILIATION_CHOICES, default=UNDERGRADUATE
)
image = models.ImageField(upload_to=get_user_file_name, null=True, blank=True)
uuid_secret = models.UUIDField(default=uuid.uuid4)

@@ -1428,6 +1445,36 @@ class Profile(models.Model):
school = models.ManyToManyField(School, blank=True)
major = models.ManyToManyField(Major, blank=True)

def detect_information(self):
"""
Try to detect appropriate values for profile fields based on what platform has
returned. Currently only supports detecting the affiliation.
This method is not very accurate and should only be used to provide the user
an initial guess.
Overwrites existing information.
"""

# detect the affilation
if self.user.groups.filter(name="platform_student").exists():
# if the user has the student group from platform, they're probably student
domain = self.user.email.split("@", 1)[-1].lower()
if domain in {
"nursing.upenn.edu",
"sas.upenn.edu",
"seas.upenn.edu",
"upenn.edu",
"wharton.upenn.edu",
}:
# domains commonly associated with undergrad schools marked as undergrad
self.affiliation = Profile.UNDERGRADUATE
else:
self.affiliation = Profile.MASTERS
else:
self.affiliation = Profile.STAFF

self.save(update_fields=["affiliation"])

def __str__(self):
return self.user.username

2 changes: 2 additions & 0 deletions backend/clubs/serializers.py
Original file line number Diff line number Diff line change
@@ -1783,6 +1783,7 @@ class UserSerializer(serializers.ModelSerializer):
graduation_year = serializers.IntegerField(
source="profile.graduation_year", allow_null=True
)
affiliation = serializers.IntegerField(source="profile.affiliation")
school = SchoolSerializer(many=True, source="profile.school")
major = MajorSerializer(many=True, source="profile.major")

@@ -1841,6 +1842,7 @@ def update(self, instance, validated_data):
class Meta:
model = get_user_model()
fields = [
"affiliation",
"email",
"graduation_year",
"has_been_prompted",
16 changes: 16 additions & 0 deletions frontend/components/Settings/ProfileForm.tsx
Original file line number Diff line number Diff line change
@@ -80,6 +80,14 @@ const ProfileForm = ({
}
}

const affiliations = [
{ value: 0, label: 'Undergraduate Student' },
{ value: 1, label: 'Masters Student' },
{ value: 2, label: 'Professional Student' },
{ value: 3, label: 'Doctoral Student' },
{ value: 4, label: 'Faculty or Staff Member' },
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ArmaanT Rerequesting review so I can get your opinion on these labels. Are there better labels that we can use? What is the difference between a masters and a professional student? They generally seem very intertwined when Penn refers to them, would everyone be able to tell which one they should select?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On platform we're using the labels that Penn used to label degrees (link). I'm sure Penn isn't very consistent in their naming, but I think this should be good enough for us. There are definitely conflicts (for example an Accounting MBA is both a Master's and a Professional degree) so we just choose the first label that applies. Bachelor's, then Master's, then PhD, then Professional

]

return (
<>
<Formik
@@ -97,6 +105,14 @@ const ProfileForm = ({
isImage
/>
<Field name="graduation_year" as={TextField} type="number" />
<Field
name="affiliation"
as={SelectField}
choices={affiliations}
valueDeserialize={(val) =>
affiliations.find((item) => item.value === val)
}
/>
<Field name="school" as={SelectField} choices={schools} isMulti />
<Field name="major" as={SelectField} choices={majors} isMulti />
<Field