Remove avatar field in user and add section field

This commit is contained in:
Keannu Bernasol 2024-01-14 20:57:27 +08:00
parent 4a26f6ae3e
commit 85fb489352
8 changed files with 49 additions and 53 deletions

View file

@ -1,10 +1,9 @@
# Generated by Django 4.2.7 on 2024-01-05 10:26 # Generated by Django 5.0.1 on 2024-01-14 12:55
import accounts.models
import django.contrib.auth.models import django.contrib.auth.models
import django.contrib.auth.validators import django.contrib.auth.validators
from django.db import migrations, models
import django.utils.timezone import django.utils.timezone
from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -33,7 +32,7 @@ class Migration(migrations.Migration):
('is_technician', models.BooleanField(default=False)), ('is_technician', models.BooleanField(default=False)),
('is_teacher', models.BooleanField(default=False)), ('is_teacher', models.BooleanField(default=False)),
('course', models.CharField(choices=[('BS Chemistry', 'BS Chemistry'), ('BS Food Technology', 'BS Food Technology'), ('BS Applied Physics', 'BS Applied Physics'), ('BS Environmental Science', 'BS Environmental Science')], default=None, max_length=60, null=True)), ('course', models.CharField(choices=[('BS Chemistry', 'BS Chemistry'), ('BS Food Technology', 'BS Food Technology'), ('BS Applied Physics', 'BS Applied Physics'), ('BS Environmental Science', 'BS Environmental Science')], default=None, max_length=60, null=True)),
('avatar', models.ImageField(null=True, upload_to=accounts.models.CustomUser._get_upload_to)), ('section', models.CharField(default=None, max_length=60, null=True)),
('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')),
('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')),
], ],

View file

@ -1,35 +1,12 @@
from django.db import models
from django.db.models.signals import post_migrate
from django.contrib.auth.models import AbstractUser from django.contrib.auth.models import AbstractUser
from django.db import models from django.db import models
from django.db.models.signals import post_migrate
from django.dispatch import receiver from django.dispatch import receiver
import os import os
from uuid import uuid4
class CustomUser(AbstractUser): class CustomUser(AbstractUser):
# Function for avatar uploads
def _get_upload_to(instance, filename):
base_filename, file_extension = os.path.splitext(filename)
# Get the student ID number
ext = base_filename.split('.')[-1]
filename = '{}.{}'.format(uuid4().hex, ext)
student_id = str(instance.student_id_number)
new_filename = f"{student_id}_{filename}_{file_extension}"
return os.path.join('avatars', new_filename)
# Delete old avatar file if new one is uploaded
def save(self, *args, **kwargs):
try:
# is the object in the database yet?
this = CustomUser.objects.get(id=self.id)
if this.avatar != self.avatar:
this.avatar.delete(save=False)
except:
pass # when new photo then we do nothing, normal case
super(CustomUser, self).save(*args, **kwargs)
first_name = models.CharField(max_length=100) first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100)
# Email inherited from base user class # Email inherited from base user class
@ -49,7 +26,7 @@ class CustomUser(AbstractUser):
course = models.CharField( course = models.CharField(
max_length=60, null=True, choices=COURSE_CHOICES, default=None) max_length=60, null=True, choices=COURSE_CHOICES, default=None)
avatar = models.ImageField(upload_to=_get_upload_to, null=True) section = models.CharField(max_length=60, null=True, default=None)
@property @property
def full_name(self): def full_name(self):

View file

@ -1,39 +1,38 @@
from djoser.serializers import UserCreateSerializer as BaseUserRegistrationSerializer
from djoser.serializers import UserSerializer as BaseUserSerializer from djoser.serializers import UserSerializer as BaseUserSerializer
from django.core import exceptions as django_exceptions from django.core import exceptions as django_exceptions
from rest_framework import serializers from rest_framework import serializers
from accounts.models import CustomUser from accounts.models import CustomUser
from rest_framework.settings import api_settings from rest_framework.settings import api_settings
from django.contrib.auth.password_validation import validate_password from django.contrib.auth.password_validation import validate_password
from django.utils.encoding import smart_str
from drf_spectacular.utils import extend_schema_field
from drf_spectacular.types import OpenApiTypes
from drf_extra_fields.fields import Base64ImageField
# There can be multiple subject instances with the same name, only differing in course, year level, and semester. We filter them here # There can be multiple subject instances with the same name, only differing in course, year level, and semester. We filter them here
class CustomUserSerializer(BaseUserSerializer): class CustomUserSerializer(BaseUserSerializer):
avatar = Base64ImageField() course = serializers.ChoiceField(
choices=CustomUser.COURSE_CHOICES, allow_blank=True, allow_null=True)
section = serializers.CharField(allow_blank=True, allow_null=True)
class Meta(BaseUserSerializer.Meta): class Meta(BaseUserSerializer.Meta):
model = CustomUser model = CustomUser
fields = ('id', 'username', 'email', 'avatar', 'first_name', fields = ('id', 'username', 'email', 'first_name', 'course', 'section',
'last_name', 'is_teacher', 'is_technician') 'last_name', 'is_teacher', 'is_technician')
read_only_fields = ('id', 'username', 'email',
'is_teacher', 'is_technician')
class UserRegistrationSerializer(serializers.ModelSerializer): class UserRegistrationSerializer(serializers.ModelSerializer):
email = serializers.EmailField(required=True) email = serializers.EmailField(required=True)
course = serializers.ChoiceField( course = serializers.ChoiceField(
choices=CustomUser.COURSE_CHOICES, required=True) choices=CustomUser.COURSE_CHOICES, allow_blank=True, allow_null=True)
section = serializers.CharField(allow_blank=True, allow_null=True)
password = serializers.CharField( password = serializers.CharField(
write_only=True, style={'input_type': 'password', 'placeholder': 'Password'}) write_only=True, style={'input_type': 'password', 'placeholder': 'Password'})
class Meta: class Meta:
model = CustomUser # Use your custom user model here model = CustomUser # Use your custom user model here
fields = ('username', 'email', 'password', 'avatar', 'course', fields = ('username', 'email', 'password', 'course', 'section',
'first_name', 'last_name') 'first_name', 'last_name')
read_only_fields = ('is_teacher', 'is_technician') read_only_fields = ('username', 'email', 'is_teacher', 'is_technician')
def validate(self, attrs): def validate(self, attrs):
user = self.Meta.model(**attrs) user = self.Meta.model(**attrs)

View file

@ -1139,6 +1139,9 @@ components:
required: required:
- token - token
- uid - uid
BlankEnum:
enum:
- ''
BreakageReport: BreakageReport:
type: object type: object
properties: properties:
@ -1210,12 +1213,18 @@ components:
format: email format: email
title: Email address title: Email address
maxLength: 254 maxLength: 254
avatar:
type: string
format: uri
first_name: first_name:
type: string type: string
maxLength: 100 maxLength: 100
course:
nullable: true
oneOf:
- $ref: '#/components/schemas/CourseEnum'
- $ref: '#/components/schemas/NullEnum'
section:
type: string
nullable: true
maxLength: 60
last_name: last_name:
type: string type: string
maxLength: 100 maxLength: 100
@ -1224,7 +1233,6 @@ components:
is_technician: is_technician:
type: boolean type: boolean
required: required:
- avatar
- first_name - first_name
- id - id
- last_name - last_name
@ -1448,6 +1456,9 @@ components:
- history_user - history_user
- id - id
- name - name
NullEnum:
enum:
- null
PasswordResetConfirm: PasswordResetConfirm:
type: object type: object
properties: properties:
@ -1477,12 +1488,18 @@ components:
format: email format: email
title: Email address title: Email address
maxLength: 254 maxLength: 254
avatar:
type: string
format: uri
first_name: first_name:
type: string type: string
maxLength: 100 maxLength: 100
course:
nullable: true
oneOf:
- $ref: '#/components/schemas/CourseEnum'
- $ref: '#/components/schemas/NullEnum'
section:
type: string
nullable: true
maxLength: 60
last_name: last_name:
type: string type: string
maxLength: 100 maxLength: 100
@ -1731,12 +1748,15 @@ components:
password: password:
type: string type: string
writeOnly: true writeOnly: true
avatar:
type: string
format: uri
nullable: true
course: course:
$ref: '#/components/schemas/CourseEnum' nullable: true
oneOf:
- $ref: '#/components/schemas/CourseEnum'
- $ref: '#/components/schemas/BlankEnum'
- $ref: '#/components/schemas/NullEnum'
section:
type: string
nullable: true
first_name: first_name:
type: string type: string
maxLength: 100 maxLength: 100
@ -1749,6 +1769,7 @@ components:
- first_name - first_name
- last_name - last_name
- password - password
- section
- username - username
UsernameResetConfirm: UsernameResetConfirm:
type: object type: object