Skip to content

Commit

Permalink
new migration!!!!!
Browse files Browse the repository at this point in the history
fixes the postgres issue
  • Loading branch information
JasonLovesDoggo committed Jan 4, 2024
1 parent ccad3c7 commit e268863
Show file tree
Hide file tree
Showing 5 changed files with 176 additions and 54 deletions.
11 changes: 8 additions & 3 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ db.sqlite3
_build
/.direnv
node_modules/
/test-results/
/playwright-report/
/playwright/.cache/
celerybeat-schedule
Dockerfile
docker-compose.yml
LICENSE
flake.nix
flake.lock
_config.yml
README.md

67 changes: 41 additions & 26 deletions core/management/commands/migrate_staff.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,47 @@
from django.core.management.base import BaseCommand
from django.db import IntegrityError
from django.conf import settings
from core.models import StaffMember, User # Update 'your_app' with the actual name of your app
from core.models import (
StaffMember,
User,
) # Update 'your_app' with the actual name of your app


class Command(BaseCommand):
help = 'Populate staff members based on METROPOLIS_STAFFS and bio settings.'

def handle(self, *args, **options):
try:
for position, user_ids in settings.METROPOLIS_STAFFS.items():
for user_id in user_ids:
try:
user = User.objects.get(pk=user_id)
bio = settings.METROPOLIS_STAFF_BIO.get(user_id, "")
if not bio:
print(f"Bio for user {user.username} ID:{user.id} is empty")
staff_member, created = StaffMember.objects.get_or_create(
user=user, bio=bio
)
staff_member.positions = list(staff_member.positions) + [position]
staff_member.save()
except User.DoesNotExist:
self.stdout.write(self.style.ERROR(f"User {user_id} does not exist"))
except IntegrityError:
self.stdout.write(self.style.WARNING(f"StaffMember for user {user_id} already exists"))

except AttributeError:
self.stdout.write(self.style.SUCCESS("METROPOLIS_STAFFS does not exist anymore"))

self.stdout.write(self.style.SUCCESS("Command completed successfully"))
help = "Populate staff members based on METROPOLIS_STAFFS and bio settings."

def handle(self, *args, **options):
try:
for position, user_ids in settings.METROPOLIS_STAFFS.items():
for user_id in user_ids:
try:
user = User.objects.get(pk=user_id)
bio = settings.METROPOLIS_STAFF_BIO.get(user_id, "")
if not bio:
print(
f"Bio for user {user.username} ID:{user.id} is empty"
)
staff_member, created = StaffMember.objects.get_or_create(
user=user, bio=bio
)
staff_member.positions = list(staff_member.positions) + [
position
]
staff_member.save()
except User.DoesNotExist:
self.stdout.write(
self.style.ERROR(f"User {user_id} does not exist")
)
except IntegrityError:
self.stdout.write(
self.style.WARNING(
f"StaffMember for user {user_id} already exists"
)
)

except AttributeError:
self.stdout.write(
self.style.SUCCESS("METROPOLIS_STAFFS does not exist anymore")
)

self.stdout.write(self.style.SUCCESS("Command completed successfully"))
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Generated by Django 5.0 on 2024-01-04 12:02

import core.utils.fields
import django.db.models.functions.text
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("auth", "0012_alter_user_first_name_max_length"),
("core", "0069_staffmember_alter_user_options_and_more"),
]

operations = [
migrations.RemoveConstraint(
model_name="staffmember",
name="unique_staff_member",
),
migrations.AlterField(
model_name="staffmember",
name="positions",
field=core.utils.fields.ChoiceArrayField(
base_field=models.CharField(
choices=[
("Project Manager", "Project Manager"),
("Frontend Developer", "Frontend Developer"),
("Backend Developer", "Backend Developer"),
("App Developer", "App Developer"),
("Graphic Designer", "Graphic Designer"),
("Content Creator", "Content Creator"),
("Doodle Developer", "Doodle Developer"),
]
),
help_text="The positions the user had/does hold.",
size=None,
),
),
migrations.AlterField(
model_name="staffmember",
name="positions_leading",
field=core.utils.fields.ChoiceArrayField(
base_field=models.CharField(
choices=[
("Frontend Developer", "Frontend Developer"),
("Backend Developer", "Backend Developer"),
("App Developer", "App Developer"),
("Graphic Designer", "Graphic Designer"),
("Content Creator", "Content Creator"),
("Doodle Developer", "Doodle Developer"),
]
),
blank=True,
null=True,
size=None,
),
),
migrations.AlterField(
model_name="staffmember",
name="years",
field=core.utils.fields.ChoiceArrayField(
base_field=models.CharField(
choices=[
("2021-2022", "2021-2022"),
("2022-2023", "2022-2023"),
("2023-2024", "2023-2024"),
("2024-2025", "2024-2025"),
]
),
help_text="The years the user was a staff member. Used to determine if the user is an alumni.",
size=None,
),
),
migrations.AddConstraint(
model_name="user",
constraint=models.UniqueConstraint(
django.db.models.functions.text.Lower("username"),
name="username-lower-check",
),
),
]
14 changes: 4 additions & 10 deletions core/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from .course import Term
from .post import Announcement
from ..utils import calculate_years
from ..utils.fields import SetField, ArrayField
from ..utils.fields import SetField, ChoiceArrayField


# Create your models here.
Expand Down Expand Up @@ -115,11 +115,11 @@ class StaffMember(models.Model):
null=False,
help_text="The users staff bio (displayed on the staff page).",
)
positions = ArrayField(
positions = ChoiceArrayField(
base_field=CharField(choices=settings.METROPOLIS_POSITIONS),
help_text="The positions the user had/does hold.",
)
positions_leading = ArrayField(
positions_leading = ChoiceArrayField(
blank=True,
null=True,
base_field=CharField(
Expand All @@ -131,7 +131,7 @@ class StaffMember(models.Model):
),
)

years = ArrayField(
years = ChoiceArrayField(
base_field=CharField(choices=calculate_years(fmt="generate")),
help_text="The years the user was a staff member. Used to determine if the user is an alumni.",
)
Expand All @@ -150,9 +150,3 @@ def is_alumni(self):
class Meta:
verbose_name = "Staff Member"
verbose_name_plural = "Staff Members"
constraints = [
models.UniqueConstraint(
fields=["user"],
name="unique_staff_member",
)
]
58 changes: 43 additions & 15 deletions core/utils/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,20 @@

from django.conf import settings
from django.core.exceptions import ValidationError
from django.db import models, connection
from django.db.models.fields import PositiveIntegerRelDbTypeMixin, SmallIntegerField, CharField
from django.db import models
from django.db.models.fields import PositiveIntegerRelDbTypeMixin, SmallIntegerField
from django.forms import DateInput, DateField
from django.utils import timezone
from django.utils.dateparse import parse_date
from django.utils.translation import gettext_lazy as _
import json

from django import forms
from django.db.models import JSONField as DjangoJSONField
from django.contrib.postgres.fields import (
ArrayField as DjangoArrayField,
)
from django.db.models import Field


class MonthDayFormField(DateField):
Expand Down Expand Up @@ -158,30 +166,24 @@ def _get_val_from_obj(self, obj):
return getattr(obj, self.attname)


import json

from django import forms
from django.db.models import JSONField as DjangoJSONField
from django.contrib.postgres.fields import (
ArrayField as DjangoArrayField,
)
from django.db.models import Field


class JSONField(DjangoJSONField):
pass


class _TypedMultipleChoiceField(forms.TypedMultipleChoiceField):
def __init__(self, *args, **kwargs):
kwargs.pop("base_field", None)
kwargs.pop("max_length", None)
super().__init__(*args, **kwargs)


class ArrayField(DjangoArrayField):
def formfield(self, **kwargs):
defaults = {
"form_class": forms.MultipleChoiceField,
"choices": self.base_field.choices,
}
kwargs.pop("base_field", None)
defaults.update(kwargs)

# Update the 'base_field' attribute with the instance of the base field
return super(ArrayField, self).formfield(**defaults)


Expand Down Expand Up @@ -240,3 +242,29 @@ def formfield(self, **kwargs):
# care for it.
# pylint:disable=bad-super-call
return super().formfield(**defaults)


class ChoiceArrayField(ArrayField): # credit goes to https://github.com/anyidea
"""
A field that allows us to store an array of choices.
Uses Django 4.2's postgres ArrayField
and a TypeMultipleChoiceField for its formfield.
Usage:
choices = ChoiceArrayField(
models.CharField(max_length=..., choices=(...,)), blank=[...], default=[...]
)
"""

def formfield(self, **kwargs):
defaults = {
"form_class": _TypedMultipleChoiceField,
"choices": self.base_field.choices,
"coerce": self.base_field.to_python,
}
defaults.update(kwargs)
# Skip our parent's formfield implementation completely as we don't care for it.
# pylint:disable=bad-super-call
return super().formfield(**defaults)

0 comments on commit e268863

Please sign in to comment.