Skip to content

Commit

Permalink
setup first class with base model
Browse files Browse the repository at this point in the history
  • Loading branch information
magsyg committed Jan 2, 2024
1 parent 5c20a74 commit e8ff7dd
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 39 deletions.
17 changes: 16 additions & 1 deletion backend/root/custom_classes/admin_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from django.http import HttpRequest
from django.urls import reverse
from django.contrib import admin
from django.db.models import QuerySet
from django.db.models import QuerySet, Model
from django.contrib.auth.admin import UserAdmin, GroupAdmin

from admin_auto_filters.filters import AutocompleteFilter
Expand Down Expand Up @@ -265,3 +265,18 @@ 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']

def save_model(self, request: HttpRequest, obj: Model, form: Any, change: Any) -> Any:
if not change:
obj.created_by = request.user
obj.updated_by = request.user

return super().save_model(request, obj, form, change)
44 changes: 20 additions & 24 deletions backend/root/utils/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
from typing import Any, Union

from django.db import models

from django.http import HttpRequest
from django.core.exceptions import ValidationError
from django.contrib import admin
from rest_framework import serializers
from django.db.models import DEFERRED, Model

from rest_framework import status, serializers
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

LOG = logging.getLogger(__name__)


Expand Down Expand Up @@ -182,6 +183,8 @@ def save(self, *args: Any, **kwargs: Any) -> None:


class CustomBaseSerializer(serializers.ModelSerializer):
created_by = serializers.SerializerMethodField(method_name='get_created_by', read_only=True)
updated_by = serializers.SerializerMethodField(method_name='get_updated_by', read_only=True)
"""
Base serializer, sets version fields to read_only
Adds validation errors from models clean
Expand All @@ -197,6 +200,12 @@ class Meta:
'updated_by',
)

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

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

def validate(self, attrs: dict) -> dict:
instance: FullCleanSaveMixin = self.Meta.model(**attrs)
try:
Expand All @@ -211,21 +220,6 @@ def create(self, validated_data: dict) -> CustomBaseModel:
return instance


class CustomBaseAdmin(admin.ModelAdmin):
"""
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']

def save_model(self, request: HttpRequest, obj: Model, form: Any, change: Any) -> Any:
if not change:
obj.created_by = request.user
obj.updated_by = request.user

return super().save_model(request, obj, form, change)


class CustomBaseModel(FullCleanSaveMixin):
"""
Basic model which will contains necessary version info of a model:
Expand All @@ -240,11 +234,12 @@ class CustomBaseModel(FullCleanSaveMixin):
)

created_by = models.ForeignKey(
'samfundet.User',
'User',
null=True,
blank=True,
on_delete=models.SET_NULL,
editable=False,
related_name='created',
)
created_at = models.DateTimeField(
null=True,
Expand All @@ -254,11 +249,12 @@ class CustomBaseModel(FullCleanSaveMixin):
)

updated_by = models.ForeignKey(
'samfundet.User',
'User',
null=True,
blank=True,
on_delete=models.SET_NULL,
editable=False,
related_name='updated',
)
updated_at = models.DateTimeField(
null=True,
Expand All @@ -285,7 +281,7 @@ def save(self, *args: Any, **kwargs: Any) -> None:
self.version += 1
user = kwargs.pop('user', None) # Must pop because super().save() doesn't accept user
if user:
self.last_editor = user
if not self.id:
self.creator = user
self.updated_by = user
if self.created_by is None:
self.created_by = user
super().save(*args, **kwargs)
9 changes: 3 additions & 6 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 @@ -305,7 +302,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 Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Generated by Django 5.0 on 2024-01-02 12:31

import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("samfundet", "0002_alter_notification_options_and_more"),
]

operations = [
migrations.AddField(
model_name="informationpage",
name="created_by",
field=models.ForeignKey(
blank=True,
editable=False,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="created",
to=settings.AUTH_USER_MODEL,
),
),
migrations.AddField(
model_name="informationpage",
name="updated_by",
field=models.ForeignKey(
blank=True,
editable=False,
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="updated",
to=settings.AUTH_USER_MODEL,
),
),
migrations.AddField(
model_name="informationpage",
name="version",
field=models.PositiveIntegerField(
blank=True, default=0, editable=False, null=True
),
),
]
9 changes: 2 additions & 7 deletions backend/samfundet/models/general.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from guardian.shortcuts import assign_perm
from django.utils.translation import gettext as _

from root.utils.mixins import FullCleanSaveMixin
from root.utils.mixins import FullCleanSaveMixin, CustomBaseModel
from root.utils import permissions

from .utils.fields import LowerCaseField, PhoneNumberField
Expand Down Expand Up @@ -317,7 +317,7 @@ def __str__(self) -> str:
return f'{self.gang_type} - {self.name_nb}'


class InformationPage(FullCleanSaveMixin):
class InformationPage(CustomBaseModel):
slug_field = models.SlugField(
max_length=64,
blank=True,
Expand All @@ -333,11 +333,6 @@ class InformationPage(FullCleanSaveMixin):
title_en = models.CharField(max_length=64, blank=True, null=True, verbose_name='Tittel (engelsk)')
text_en = models.TextField(blank=True, null=True, verbose_name='Tekst (engelsk)')

created_at = models.DateTimeField(null=True, blank=True, auto_now_add=True)
updated_at = models.DateTimeField(null=True, blank=True, auto_now=True)

# TODO Find usage for owner field

class Meta:
verbose_name = 'InformationPage'
verbose_name_plural = 'InformationPages'
Expand Down
3 changes: 2 additions & 1 deletion backend/samfundet/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from django.db.models import QuerySet
from guardian.models import GroupObjectPermission, UserObjectPermission

from root.utils.mixins import CustomBaseSerializer
from rest_framework import serializers
from root.constants import PHONE_NUMBER_REGEX
from .models.billig import BilligEvent, BilligTicketGroup, BilligPriceGroup
Expand Down Expand Up @@ -389,7 +390,7 @@ class Meta:
fields = '__all__'


class InformationPageSerializer(serializers.ModelSerializer):
class InformationPageSerializer(CustomBaseSerializer):

class Meta:
model = InformationPage
Expand Down

0 comments on commit e8ff7dd

Please sign in to comment.