diff --git a/apps/official/BiscuIT-App-Alsijil b/apps/official/BiscuIT-App-Alsijil index 45bf10456b2a68b6773c8c74feb0698447dd8e48..a0c50e1881df1c19cbbccc472f24b0012b2fa482 160000 --- a/apps/official/BiscuIT-App-Alsijil +++ b/apps/official/BiscuIT-App-Alsijil @@ -1 +1 @@ -Subproject commit 45bf10456b2a68b6773c8c74feb0698447dd8e48 +Subproject commit a0c50e1881df1c19cbbccc472f24b0012b2fa482 diff --git a/apps/official/BiscuIT-App-Chronos b/apps/official/BiscuIT-App-Chronos index 58e71f31a69cc5dddbc676d6fc8b1b9f93820f57..fea3df1800f9cbf1b0b17f23d322fa9964d90e91 160000 --- a/apps/official/BiscuIT-App-Chronos +++ b/apps/official/BiscuIT-App-Chronos @@ -1 +1 @@ -Subproject commit 58e71f31a69cc5dddbc676d6fc8b1b9f93820f57 +Subproject commit fea3df1800f9cbf1b0b17f23d322fa9964d90e91 diff --git a/apps/official/BiscuIT-App-Exlibris b/apps/official/BiscuIT-App-Exlibris index 530a8e3b69fe838d0e08c46da4b3a1600c5b2417..efdf82d5df68807ad6f03bcea598b06264f8c5df 160000 --- a/apps/official/BiscuIT-App-Exlibris +++ b/apps/official/BiscuIT-App-Exlibris @@ -1 +1 @@ -Subproject commit 530a8e3b69fe838d0e08c46da4b3a1600c5b2417 +Subproject commit efdf82d5df68807ad6f03bcea598b06264f8c5df diff --git a/apps/official/BiscuIT-App-SchILD-NRW b/apps/official/BiscuIT-App-SchILD-NRW index 3d622c220ac7979c1ba864c4da9df2fcd58cf70c..b009a2b137cf637c830fed9223e73d1b805a3580 160000 --- a/apps/official/BiscuIT-App-SchILD-NRW +++ b/apps/official/BiscuIT-App-SchILD-NRW @@ -1 +1 @@ -Subproject commit 3d622c220ac7979c1ba864c4da9df2fcd58cf70c +Subproject commit b009a2b137cf637c830fed9223e73d1b805a3580 diff --git a/apps/official/BiscuIT-App-Untis b/apps/official/BiscuIT-App-Untis index 4b4cd60ac4d1b4b9ed706550adeb3f4a669ff1b1..c437e7e151c9b16d6bddac9ef7acb3539943d6c5 160000 --- a/apps/official/BiscuIT-App-Untis +++ b/apps/official/BiscuIT-App-Untis @@ -1 +1 @@ -Subproject commit 4b4cd60ac4d1b4b9ed706550adeb3f4a669ff1b1 +Subproject commit c437e7e151c9b16d6bddac9ef7acb3539943d6c5 diff --git a/biscuit/core/migrations/0014_remove_unique.py b/biscuit/core/migrations/0014_remove_unique.py new file mode 100644 index 0000000000000000000000000000000000000000..d985917972616b5c30cf700fb0333c7bf72f54da --- /dev/null +++ b/biscuit/core/migrations/0014_remove_unique.py @@ -0,0 +1,23 @@ +# Generated by Django 2.2.4 on 2019-08-22 19:26 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0013_person_primary_group'), + ] + + operations = [ + migrations.AlterField( + model_name='group', + name='name', + field=models.CharField(max_length=30, verbose_name='Long name of group'), + ), + migrations.AlterField( + model_name='group', + name='short_name', + field=models.CharField(max_length=8, verbose_name='Short name of group'), + ), + ] diff --git a/biscuit/core/models.py b/biscuit/core/models.py index 500af9b0c5f5c0d22d314ad93bdb3df4f84ed583..a1991a538111f5c0a63c9ccb5164311ba9a11dc9 100644 --- a/biscuit/core/models.py +++ b/biscuit/core/models.py @@ -1,3 +1,5 @@ +from typing import Optional + from django.contrib.auth import get_user_model from django.db import models from django.utils.translation import ugettext_lazy as _ @@ -76,6 +78,33 @@ class Person(SchoolRelated): primary_group = models.ForeignKey('Group', models.SET_NULL, null=True) + @property + def primary_group_short_name(self) -> Optional[str]: + """ Returns the short_name field of the primary + group related object. + """ + + if self.primary_group: + return self.primary_group.short_name + @primary_group_short_name.setter + def primary_group_short_name(self, value: str) -> None: + """ Sets the primary group related object by + a short name. It uses the first existing group + with this short name it can find, creating one + if it can't find one. + """ + + group, created = Group.objects.get_or_create(short_name=value, + defaults={'name': value}) + self.primary_group = group + + def save(self, *args, **kwargs): + if self.primary_group: + if self.primary_group not in self.member_of.all(): + self.member_of.add(self.primary_group) + + return super().save(*args, **kwargs) + def __str__(self) -> str: return '%s, %s' % (self.last_name, self.first_name) @@ -89,9 +118,9 @@ class Group(SchoolRelated): unique_together = [['school', 'name'], ['school', 'short_name']] name = models.CharField(verbose_name=_( - 'Long name of group'), max_length=30, unique=True) + 'Long name of group'), max_length=30) short_name = models.CharField(verbose_name=_( - 'Short name of group'), max_length=8, unique=True) + 'Short name of group'), max_length=8) members = models.ManyToManyField('Person', related_name='member_of') owners = models.ManyToManyField('Person', related_name='owner_of') diff --git a/biscuit/core/templates/core/group_full.html b/biscuit/core/templates/core/group_full.html index d4c0854be55f523c8bd670a1956c9b4a154a6614..92965a72c15bf151f192da23cbd69372994ca473 100644 --- a/biscuit/core/templates/core/group_full.html +++ b/biscuit/core/templates/core/group_full.html @@ -1,5 +1,6 @@ {% extends "core/base.html" %} {% load bootstrap4 font_awesome i18n staticfiles %} +{% load render_table from django_tables2 %} {% block content %} <div class="col-sm-12 col-md-12"> diff --git a/biscuit/core/util/core_helpers.py b/biscuit/core/util/core_helpers.py index 94ffde727a44c9eb516ef3b42cac38d8b2377ae3..23efbf02b06f569b9ef64c2a9443a033b7a8ad35 100644 --- a/biscuit/core/util/core_helpers.py +++ b/biscuit/core/util/core_helpers.py @@ -4,8 +4,6 @@ from typing import Optional, Sequence from django_global_request.middleware import get_request -from ..models import School - def get_app_packages() -> Sequence[str]: """ Find all packages within the biscuit.apps namespace. """ @@ -31,7 +29,8 @@ def get_app_packages() -> Sequence[str]: return pkgs -def get_current_school() -> Optional[School]: +# FIXME Use more specific result type +def get_current_school() -> Optional: request = get_request() if request: diff --git a/biscuit/core/util/messages.py b/biscuit/core/util/messages.py index 98a273b90eab32a9de5961a5542355f2acbfebe0..7b847885567b989100b89de4c830d73f4346bb70 100644 --- a/biscuit/core/util/messages.py +++ b/biscuit/core/util/messages.py @@ -1,32 +1,32 @@ import logging -from typing import Optional +from typing import Any, Optional from django.contrib import messages from django.http import HttpRequest -def add_message(request: Optional[HttpRequest], level: int, message: str, **kwargs) -> Any: +def add_message(request: Optional[HttpRequest], level: int, message: str, **kwargs) -> Optional[Any]: if request: return messages.add_message(request, level, message, **kwargs) else: return logging.getLogger(__name__).log(level, message) -def debug(request: Optional[HttpRequest], message: str, **kwargs) -> Any +def debug(request: Optional[HttpRequest], message: str, **kwargs) -> Optional[Any]: return add_message(request, messages.DEBUG, message, **kwargs) -def info(request: Optional[HttpRequest], message: str, **kwargs) -> Any +def info(request: Optional[HttpRequest], message: str, **kwargs) -> Optional[Any]: return add_message(request, messages.INFO, message, **kwargs) -def success(request: Optional[HttpRequest], message: str, **kwargs) -> Any +def success(request: Optional[HttpRequest], message: str, **kwargs) -> Optional[Any]: return add_message(request, messages.SUCCESS, message, **kwargs) -def warning(request: Optional[HttpRequest], message: str, **kwargs) -> Any +def warning(request: Optional[HttpRequest], message: str, **kwargs) -> Optional[Any]: return add_message(request, messages.WARNING, message, **kwargs) -def error(request: Optional[HttpRequest], message: str, **kwargs) -> Any +def error(request: Optional[HttpRequest], message: str, **kwargs) -> Optional[Any]: return add_message(request, messages.ERROR, message, **kwargs) diff --git a/biscuit/core/views.py b/biscuit/core/views.py index b4a4d6635468c59b628b7189ed9c090b985919ca..968e983943645aa2cc5275b2183cf63f444614ce 100644 --- a/biscuit/core/views.py +++ b/biscuit/core/views.py @@ -1,3 +1,5 @@ +from typing import Callable + from django.contrib.auth.decorators import login_required from django.conf import settings from django.http import Http404, HttpRequest, HttpResponse @@ -87,7 +89,7 @@ def group(request: HttpRequest, id_: int, template: str) -> HttpResponse: group = Group.objects.get(pk=id_) # Get members - persons = group.members + persons = group.members.all() # Build table persons_table = PersonsTable(persons) diff --git a/dev.sh b/dev.sh index 1d1f310eeb2f3e5fedd13b120ade7762f5022fc9..0dc003da156de64c8f16db13f28260080dd37dfa 100755 --- a/dev.sh +++ b/dev.sh @@ -1,5 +1,7 @@ #!/bin/sh +set -e + remove_pip_metadata() { find . -type d -name pip-wheel-metadata -print0 | xargs -0r rm -rf -- } @@ -16,7 +18,7 @@ case "$1" in remove_pip_metadata poetry run ./manage.py migrate poetry run ./manage.py compilemessages - poetry run ./manage.py collectstatic + poetry run ./manage.py collectstatic --no-input ;; *) ;;