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 basis for Basemodel #903

Merged
merged 17 commits into from
Jan 9, 2024
8 changes: 8 additions & 0 deletions backend/root/custom_classes/admin_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,3 +265,11 @@ class CustomGuardedUserAdmin(CustomGuardedModelAdmin, UserAdmin):

class CustomGuardedGroupAdmin(CustomGuardedModelAdmin, GroupAdmin):
...


class CustomBaseAdmin(CustomGuardedModelAdmin):
"""
Custom base admin, sets user on save
Displays these fields as read only in admi
"""
readonly_fields = ['version', 'created_by', 'created_at', 'updated_by', 'updated_at']
108 changes: 108 additions & 0 deletions backend/root/utils/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,14 @@
import logging
from typing import Any, Union

from django.db import models
from django.utils import timezone
from django.db.models import DEFERRED, Model

from rest_framework import serializers

from root.constants import request_contextvar

LOG = logging.getLogger(__name__)


Expand Down Expand Up @@ -173,3 +179,105 @@ class Meta:
def save(self, *args: Any, **kwargs: Any) -> None:
self.full_clean()
super().save(*args, **kwargs)


class CustomBaseModel(FullCleanSaveMixin):
"""
Basic model which will contains necessary version info of a model:
With by who and when it was updated and created.
Also keeps a counter for how many times it has been updated
"""
version = models.PositiveIntegerField(
default=0,
null=True,
blank=True,
editable=False,
)

created_by = models.ForeignKey(
'User',
null=True,
blank=True,
on_delete=models.SET_NULL,
editable=False,
related_name='+', # allows only one way relation, UserModel cant have different models with same related name
)
created_at = models.DateTimeField(
null=True,
blank=True,
editable=False,
)

updated_by = models.ForeignKey(
'User',
null=True,
blank=True,
on_delete=models.SET_NULL,
editable=False,
related_name='+', # allows only one way relation
)
updated_at = models.DateTimeField(
null=True,
blank=True,
editable=False,
)

class Meta:
abstract = True

def is_edited(self) -> bool:
"""
Method for checking if object is updated or not
"""
return self.updated_at != self.created_at

def save(self, *args: Any, **kwargs: Any) -> None:
"""
User should always be provided, but that can be ignored.
Will update and set which user interacted with it when it was saved.
"""
self.full_clean()
self.version += 1
emilte marked this conversation as resolved.
Show resolved Hide resolved
self.updated_at = timezone.now()
request = request_contextvar.get()
user = request.user if request else None
if user:
self.updated_by = user
if self.created_by is None:
self.created_by = user
if not self.created_at:
# instead of auto add, since they are added at different ticks
self.created_at = self.updated_at

super().save(*args, **kwargs)


class CustomBaseSerializer(serializers.ModelSerializer):
"""
Base serializer, sets version fields to read_only
Adds validation errors from models clean
Context of request needs to be passed
"""
created_by = serializers.SerializerMethodField(method_name='get_created_by', read_only=True)
updated_by = serializers.SerializerMethodField(method_name='get_updated_by', read_only=True)

class Meta:
model = CustomBaseModel
read_only_fields = (
'version',
'created_at',
'created_by',
'updated_at',
'updated_by',
)

def get_created_by(self, obj: CustomBaseModel) -> str | None:
return obj.created_by.__str__() if obj.created_by else None

def get_updated_by(self, obj: CustomBaseModel) -> str | None:
return obj.updated_by.__str__() if obj.updated_by else None

def validate(self, attrs: dict) -> dict:
instance: FullCleanSaveMixin = self.Meta.model(**attrs)
instance.full_clean()
return attrs
59 changes: 28 additions & 31 deletions backend/samfundet/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,8 @@
from guardian import models as guardian_models
from root.utils.routes import admin__samfundet_recruitmentadmission_change

from root.custom_classes.admin_classes import (
CustomGuardedUserAdmin,
CustomGuardedGroupAdmin,
CustomGuardedModelAdmin,
)
from root.custom_classes.admin_classes import (CustomGuardedUserAdmin, CustomGuardedGroupAdmin, CustomGuardedModelAdmin, CustomBaseAdmin)

from .models.event import (Event, EventGroup, EventRegistration)
from .models.recruitment import (
Recruitment,
Expand Down Expand Up @@ -224,7 +221,7 @@ class EventRegistrationAdmin(CustomGuardedModelAdmin):


@admin.register(Event)
class EventAdmin(CustomGuardedModelAdmin):
class EventAdmin(CustomBaseAdmin):
# ordering = []

sortable_by = ['id', 'title_nb', 'title_en', 'host', 'location', 'event_group', 'created_at', 'updated_at']
Expand All @@ -239,7 +236,7 @@ class EventAdmin(CustomGuardedModelAdmin):


@admin.register(Tag)
class TagAdmin(CustomGuardedModelAdmin):
class TagAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'name']
list_display = ['id', 'name', 'color']
Expand All @@ -251,7 +248,7 @@ class TagAdmin(CustomGuardedModelAdmin):


@admin.register(Image)
class ImageAdmin(CustomGuardedModelAdmin):
class ImageAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'title', 'image']
list_display = ['id', 'title', 'image']
Expand All @@ -264,7 +261,7 @@ class ImageAdmin(CustomGuardedModelAdmin):


@admin.register(EventGroup)
class EventGroupAdmin(CustomGuardedModelAdmin):
class EventGroupAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id']
# list_filter = [] # TODO
Expand All @@ -277,7 +274,7 @@ class EventGroupAdmin(CustomGuardedModelAdmin):


@admin.register(Venue)
class VenueAdmin(CustomGuardedModelAdmin):
class VenueAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'name', 'floor', 'last_renovated', 'handicapped_approved', 'responsible_crew', 'opening', 'closing', 'created_at', 'updated_at']
list_filter = ['handicapped_approved']
Expand All @@ -293,7 +290,7 @@ class VenueAdmin(CustomGuardedModelAdmin):

# GANGS:
@admin.register(Gang)
class GangAdmin(CustomGuardedModelAdmin):
class GangAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'name_nb', 'abbreviation', 'gang_type', 'created_at', 'updated_at']
list_filter = ['gang_type']
Expand All @@ -306,7 +303,7 @@ class GangAdmin(CustomGuardedModelAdmin):


@admin.register(GangType)
class GangTypeAdmin(CustomGuardedModelAdmin):
class GangTypeAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'title_nb', 'created_at', 'updated_at']
# list_filter = []
Expand All @@ -319,7 +316,7 @@ class GangTypeAdmin(CustomGuardedModelAdmin):


@admin.register(InformationPage)
class InformationPageAdmin(CustomGuardedModelAdmin):
class InformationPageAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['slug_field', 'created_at', 'updated_at']
# list_filter = []
Expand All @@ -332,7 +329,7 @@ class InformationPageAdmin(CustomGuardedModelAdmin):


@admin.register(BlogPost)
class BlogPostAdmin(CustomGuardedModelAdmin):
class BlogPostAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'title_nb', 'title_en', 'created_at', 'updated_at']
# list_filter = []
Expand All @@ -345,7 +342,7 @@ class BlogPostAdmin(CustomGuardedModelAdmin):


@admin.register(Table)
class TableAdmin(CustomGuardedModelAdmin):
class TableAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'name_nb', 'name_en', 'seating', 'created_at', 'updated_at']
# list_filter = []
Expand All @@ -358,7 +355,7 @@ class TableAdmin(CustomGuardedModelAdmin):


@admin.register(Reservation)
class ReservationAdmin(CustomGuardedModelAdmin):
class ReservationAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'name', 'email', 'phonenumber']
# list_filter = []
Expand All @@ -371,7 +368,7 @@ class ReservationAdmin(CustomGuardedModelAdmin):


@admin.register(Menu)
class MenuAdmin(CustomGuardedModelAdmin):
class MenuAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'name_nb', 'name_en', 'created_at', 'updated_at']
# list_filter = []
Expand All @@ -388,7 +385,7 @@ def menu_item_count(self, obj: Menu) -> int:


@admin.register(MenuItem)
class MenuItemAdmin(CustomGuardedModelAdmin):
class MenuItemAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'name_nb', 'name_en', 'price', 'price_member', 'order', 'created_at', 'updated_at']
# list_filter = []
Expand All @@ -401,7 +398,7 @@ class MenuItemAdmin(CustomGuardedModelAdmin):


@admin.register(FoodCategory)
class FoodCategoryAdmin(CustomGuardedModelAdmin):
class FoodCategoryAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'name_nb', 'name_en', 'order', 'created_at', 'updated_at']
# list_filter = []
Expand All @@ -414,7 +411,7 @@ class FoodCategoryAdmin(CustomGuardedModelAdmin):


@admin.register(FoodPreference)
class FoodPreferenceAdmin(CustomGuardedModelAdmin):
class FoodPreferenceAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'name_nb', 'name_en', 'created_at', 'updated_at']
# list_filter = []
Expand All @@ -427,7 +424,7 @@ class FoodPreferenceAdmin(CustomGuardedModelAdmin):


@admin.register(Saksdokument)
class SaksdokumentAdmin(CustomGuardedModelAdmin):
class SaksdokumentAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'title_nb']
# list_filter = []
Expand All @@ -439,7 +436,7 @@ class SaksdokumentAdmin(CustomGuardedModelAdmin):


@admin.register(Booking)
class BookingAdmin(CustomGuardedModelAdmin):
class BookingAdmin(CustomBaseAdmin):
# ordering = []
# list_filter = []
list_display = ['id', '__str__', 'name', 'get_duration', 'table_count', 'created_at', 'updated_at']
Expand All @@ -452,7 +449,7 @@ class BookingAdmin(CustomGuardedModelAdmin):


@admin.register(ClosedPeriod)
class ClosedPeriodAdmin(CustomGuardedModelAdmin):
class ClosedPeriodAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id']
# list_filter = [] # TODO
Expand All @@ -465,7 +462,7 @@ class ClosedPeriodAdmin(CustomGuardedModelAdmin):


@admin.register(Infobox)
class InfoboxAdmin(CustomGuardedModelAdmin):
class InfoboxAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['id', 'title_nb']
# list_filter = []
Expand All @@ -477,7 +474,7 @@ class InfoboxAdmin(CustomGuardedModelAdmin):


@admin.register(TextItem)
class TextItemAdmin(CustomGuardedModelAdmin):
class TextItemAdmin(CustomBaseAdmin):
# ordering = []
sortable_by = ['key']
# list_filter = []
Expand All @@ -497,7 +494,7 @@ class KeyValueAdmin(CustomGuardedModelAdmin):


@admin.register(Recruitment)
class RecruitmentAdmin(CustomGuardedModelAdmin):
class RecruitmentAdmin(CustomBaseAdmin):
sortable_by = [
'visible_from', 'actual_application_deadline', 'shown_application_deadline', 'reprioritization_deadline_for_applicant',
'reprioritization_deadline_for_groups', 'organization'
Expand Down Expand Up @@ -534,7 +531,7 @@ def linked_admission_text(self, obj: RecruitmentAdmission) -> str:


@admin.register(RecruitmentPosition)
class RecruitmentPositionAdmin(CustomGuardedModelAdmin):
class RecruitmentPositionAdmin(CustomBaseAdmin):
sortable_by = [
'name_nb',
'is_funksjonaer_position',
Expand All @@ -554,7 +551,7 @@ def admissions_count(self, obj: RecruitmentPosition) -> int:


@admin.register(RecruitmentAdmission)
class RecruitmentAdmissionAdmin(CustomGuardedModelAdmin):
class RecruitmentAdmissionAdmin(CustomBaseAdmin):
sortable_by = [
'id',
'recruitment_position',
Expand All @@ -577,15 +574,15 @@ class RecruitmentAdmissionAdmin(CustomGuardedModelAdmin):


@admin.register(Organization)
class OrganizationAdmin(CustomGuardedModelAdmin):
class OrganizationAdmin(CustomBaseAdmin):
sortable_by = ['id', 'name']
list_display = ['id', 'name']
search_fields = ['id', 'name']
list_select_related = True


@admin.register(InterviewRoom)
class InterviewRoomAdmin(CustomGuardedModelAdmin):
class InterviewRoomAdmin(CustomBaseAdmin):
list_filter = ['name', 'location', 'recruitment', 'gang', 'start_time', 'end_time']
list_display = ['name', 'location', 'recruitment', 'gang', 'start_time', 'end_time']
search_fields = ['name', 'location', 'recruitment__name', 'gang__name']
Expand All @@ -594,7 +591,7 @@ class InterviewRoomAdmin(CustomGuardedModelAdmin):


@admin.register(Interview)
class InterviewAdmin(CustomGuardedModelAdmin):
class InterviewAdmin(CustomBaseAdmin):
list_filter = ['id', 'notes']
list_display = ['id', 'notes']
search_fields = ['id', 'notes']
Expand Down
Loading
Loading