Skip to content
Draft
Show file tree
Hide file tree
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
125 changes: 106 additions & 19 deletions backend/backend/admin.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,52 @@
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.admin import GroupAdmin as BaseGroupAdmin
from django.contrib.auth.models import Group
from unfold.admin import ModelAdmin

from .models import *
from .models import (
Member,
Position,
Appointment,
Reference,
StudyProgram,
Section,
Team,
Application,
Role,
)

admin.site.unregister(Group)

# Register your models here.
class MemberAdmin(UserAdmin):

@admin.register(Group)
class GroupAdmin(BaseGroupAdmin, ModelAdmin):
"""Group admin with Unfold styling for managing roles/permissions."""
list_filter_submit = True


class MemberAdmin(BaseUserAdmin, ModelAdmin):
"""
Custom admin interface for the Member model.
Required as we are using ssn as the username instead of a username
and do not want a username field
and do not want a username field.
"""

model = Member
list_display = ("ssn", "email", "name", "is_staff", "is_active", "verified_email")
list_display = ("ssn", "email", "name", "status", "is_staff", "is_active", "verified_email")
list_filter = ("status", "is_staff", "is_active", "verified_email")
search_fields = ("ssn", "email", "name")
ordering = (
"ssn",
"email",
)
ordering = ("ssn", "email")
list_filter_submit = True
filter_horizontal = ("groups", "user_permissions")

fieldsets = (
(None, {"fields": ("ssn", "email", "password")}),
("Personal info", {"fields": ("name",)}),
("Personal info", {"fields": ("name", "phone_number", "study_program", "registration_year")}),
(
"Permissions",
{"fields": ("is_active", "is_staff", "is_superuser", "verified_email")},
{"fields": ("is_active", "is_staff", "is_superuser", "verified_email", "status", "groups",
"user_permissions")},
),
)
add_fieldsets = (
Expand All @@ -34,7 +56,10 @@ class MemberAdmin(UserAdmin):
"fields": (
"ssn",
"email",
"password",
"password1",
"password2",
"name",
"phone_number",
"is_active",
"is_staff",
"is_superuser",
Expand All @@ -45,10 +70,72 @@ class MemberAdmin(UserAdmin):
)


@admin.register(Team)
class TeamAdmin(ModelAdmin):
list_display = ("name_en", "name_sv")
search_fields = ("name_en", "name_sv", "desc_en", "desc_sv")
list_filter_submit = True


@admin.register(Role)
class RoleAdmin(ModelAdmin):
list_display = ("title_en", "title_sv", "team", "role_type", "archived")
list_filter = ("team", "role_type", "archived")
search_fields = ("title_en", "title_sv", "description_en", "description_sv", "team__name_en", "team__name_sv")
list_filter_submit = True


@admin.register(Position)
class PositionAdmin(ModelAdmin):
list_display = ("role", "recruitment_start", "recruitment_end", "term_from", "term_end", "appointed")
list_filter = ("role__team", "recruitment_start", "term_from")
search_fields = ("role__title_en", "role__title_sv", "comment_eng", "comment_sv")
list_filter_submit = True
date_hierarchy = "recruitment_start"


@admin.register(Application)
class ApplicationAdmin(ModelAdmin):
list_display = ("position", "member", "status", "decision_date")
list_filter = ("status", "position__role__team")
search_fields = (
"position__role__title_en",
"position__role__title_sv",
"member__name",
"member__email",
)
list_filter_submit = True


@admin.register(Appointment)
class AppointmentAdmin(ModelAdmin):
list_display = ("member", "position", "status", "appointed_date", "appointed_by")
list_filter = ("status", "position__role__team")
search_fields = ("member__name", "member__email", "position__role__title_en", "position__role__title_sv")
list_filter_submit = True
date_hierarchy = "appointed_date"


@admin.register(Reference)
class ReferenceAdmin(ModelAdmin):
list_display = ("name", "application", "email", "phone_num", "title")
search_fields = ("name", "email", "application__member__name")
list_filter_submit = True


@admin.register(Section)
class SectionAdmin(ModelAdmin):
list_display = ("abbreviation", "section_en", "section_sv")
search_fields = ("abbreviation", "section_en", "section_sv")
list_filter_submit = True


@admin.register(StudyProgram)
class StudyProgramAdmin(ModelAdmin):
list_display = ("name_en", "name_sv", "section")
list_filter = ("section",)
search_fields = ("name_en", "name_sv", "section__abbreviation")
list_filter_submit = True


admin.site.register(Member, MemberAdmin)
admin.site.register(Role)
admin.site.register(Team)
admin.site.register(Position)
admin.site.register(Application)
admin.site.register(Reference)
admin.site.register(Appointment)
31 changes: 16 additions & 15 deletions backend/backend/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,35 @@ class MemberManager(BaseUserManager):

Methods
-------
create_user(email, password=None, **extra_fields)
Creates and returns a user with an email, password and other fields.
create_superuser(email, password=None, **extra_fields)
Creates and returns a superuser with an email, password and other fields.
create_user(ssn, email, password=None, **extra_fields)
Creates and returns a user with ssn, email, password and other fields.
create_superuser(ssn, email, password=None, **extra_fields)
Creates and returns a superuser with ssn, email, password and other fields.
"""

def create_user(self, email, password=None, **extra_fields):
def create_user(self, ssn, email, password=None, **extra_fields):
if not ssn:
raise ValueError("The SSN field must be set")
if not email:
raise ValueError("The Email field must be set")

user = self.model(email=self.normalize_email(email), **extra_fields)

user.set_password(password)
user.save(using=self._db)
return user

def create_superuser(self, email, password=None, **extra_fields):
user = self.model(
ssn=ssn,
email=self.normalize_email(email),
is_staff=True,
is_superuser=True,
**extra_fields,
)
user.set_password(password)
user.save(using=self._db)

return user

def create_superuser(self, ssn, email, password=None, **extra_fields):
extra_fields.setdefault("is_staff", True)
extra_fields.setdefault("is_superuser", True)
extra_fields.setdefault("is_active", True)
extra_fields.setdefault("verified_email", True)

return self.create_user(ssn, email, password, **extra_fields)


class PositionManager(Manager):
"""Custom manager for Position model"""
Expand Down
36 changes: 31 additions & 5 deletions backend/backend/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class Member(AbstractBaseUser, PermissionsMixin):

USERNAME_FIELD = "ssn"
EMAIL_FIELD = "email"
REQUIRED_FIELDS = [] # TODO: add more fields, maybe
REQUIRED_FIELDS = ["email", "name", "phone_number"]

objects = MemberManager()

Expand Down Expand Up @@ -146,20 +146,22 @@ def has_perm(self, perm, obj=None):
if not self.verified_email:
return False

# Lets superusers and staff do anything
if self.is_superuser or self.is_staff:
# Only superusers get all permissions
if self.is_superuser:
return True

# Staff and regular users: check actual permissions
return super().has_perm(perm, obj)

def has_module_perms(self, app_label):
if not self.verified_email:
return False

# Lets superusers and staff do anything
if self.is_superuser or self.is_staff:
# Only superusers get all module permissions
if self.is_superuser:
return True

# Staff and regular users: check actual permissions
return super().has_module_perms(app_label)

@staticmethod
Expand All @@ -182,6 +184,9 @@ def find_user_by_ssn(ssn):

return None

def __str__(self):
return f"{self.name} ({self.ssn})"


class Position(models.Model):
"""
Expand Down Expand Up @@ -225,6 +230,9 @@ class Position(models.Model):
comment_eng = models.TextField(verbose_name=("Comment in English"), blank=True)
comment_sv = models.TextField(verbose_name=("Comment in Swedish"), blank=True)

def __str__(self):
return f"{self.role} ({self.term_from} - {self.term_end})"


class Appointment(models.Model):
"""
Expand Down Expand Up @@ -360,6 +368,9 @@ class Reference(models.Model):
blank=True,
)

def __str__(self):
return f"{self.name} - {self.application}"


class StudyProgram(models.Model):
"""
Expand Down Expand Up @@ -390,6 +401,9 @@ class StudyProgram(models.Model):
help_text=_("Enter the name of the section in Swedish"),
)

def __str__(self):
return self.name_en


class Section(models.Model):
"""
Expand Down Expand Up @@ -421,6 +435,9 @@ class Section(models.Model):
blank=False,
)

def __str__(self):
return f"{self.abbreviation} - {self.section_en}"


class Team(models.Model):
"""
Expand Down Expand Up @@ -477,6 +494,9 @@ class Team(models.Model):
# FieldPanel('description_sv'),
# ])]

def __str__(self):
return self.name_en


class Application(models.Model):
"""
Expand Down Expand Up @@ -556,6 +576,9 @@ class Application(models.Model):
verbose_name=_("Decision date"), null=True, blank=True
)

def __str__(self):
return f"{self.member.name} - {self.position} ({self.status})"


class Role(models.Model):
"""
Expand Down Expand Up @@ -683,3 +706,6 @@ def role_type_to_level(role_type):
# FieldPanel('role_type'),
# FieldPanel('teams', widget=CheckboxSelectMultiple),
# ])]

def __str__(self):
return f"{self.title_en} ({self.team})"
12 changes: 12 additions & 0 deletions backend/config/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
# Application definition

INSTALLED_APPS = [
"unfold",
"unfold.contrib.filters",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
Expand Down Expand Up @@ -165,3 +167,13 @@


MEDIA_ROOT = "../media"


# Django Unfold Admin Configuration
UNFOLD = {
"SITE_TITLE": "UTN Apply Admin",
"SITE_HEADER": "UTN Apply",
"SITE_SYMBOL": "diversity_3", # Material icon
"SHOW_HISTORY": True,
"SHOW_VIEW_ON_SITE": True,
}
3 changes: 3 additions & 0 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@ python-decouple==3.8

psycopg2
Pillow>=8.0.0

# Admin theme
django-unfold