diff --git a/castellum_core/Makefile b/castellum_core/Makefile index 0b72682d655df77e86254d3962939800d44d61fa..2b7bd51cd4e78484679d49202e462edfb69bda8e 100644 --- a/castellum_core/Makefile +++ b/castellum_core/Makefile @@ -10,6 +10,7 @@ bootstrap: install migrate createsuperuser castellum_core/locale/de/LC_MESSAGES/ migrate: $(MANAGEPY) migrate + $(MANAGEPY) migrate --database=subject_management makemigrations: $(MANAGEPY) makemigrations diff --git a/castellum_core/castellum_core/castellum_core/settings/default.py b/castellum_core/castellum_core/castellum_core/settings/default.py index 4fa505e84d94036c7817e5df65061137a3b62eb9..461a27377044001c7aad8d677cebb8db5aeb4eaf 100644 --- a/castellum_core/castellum_core/castellum_core/settings/default.py +++ b/castellum_core/castellum_core/castellum_core/settings/default.py @@ -21,6 +21,7 @@ INSTALLED_APPS = [ 'bootstrap4', 'castellum_auth.apps.CastellumAuthConfig', + 'subject_management', ] MIDDLEWARE = [ @@ -39,6 +40,7 @@ MIDDLEWARE = [ ROOT_URLCONF = 'castellum_core.urls' + TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', @@ -60,6 +62,10 @@ TEMPLATES = [ WSGI_APPLICATION = 'castellum_core.wsgi.application' +DATABASE_ROUTERS = [ + 'subject_management.routers.SubjectManagementRouter', +] + # Password validation AUTH_PASSWORD_VALIDATORS = [ diff --git a/castellum_core/castellum_core/castellum_core/settings/development.py b/castellum_core/castellum_core/castellum_core/settings/development.py index 3be75ce80ab6005a8a94da3a9d7ce3ee89e6700f..c4579e987fa77a7014e176c5464964bb4a2954d5 100644 --- a/castellum_core/castellum_core/castellum_core/settings/development.py +++ b/castellum_core/castellum_core/castellum_core/settings/development.py @@ -12,7 +12,11 @@ DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), - } + }, + 'subject_management': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'subject_management.sqlite3'), + }, } EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend' diff --git a/castellum_core/castellum_core/subject_management/__init__.py b/castellum_core/castellum_core/subject_management/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..6e59d7160d19057527329a8a868faa4188e50563 --- /dev/null +++ b/castellum_core/castellum_core/subject_management/__init__.py @@ -0,0 +1 @@ +default_app_config = 'subject_management.apps.SubjectManagementConfig' diff --git a/castellum_core/castellum_core/subject_management/admin/__init__.py b/castellum_core/castellum_core/subject_management/admin/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..067eaa8d31c5149c81744738256d17795b42dac3 --- /dev/null +++ b/castellum_core/castellum_core/subject_management/admin/__init__.py @@ -0,0 +1,33 @@ +# (c) 2018 +# MPIB , +# MPI-CBS , +# MPIP +# +# This file is part of Castellum. +# +# Castellum is free software; you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Castellum is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with Castellum. If not, see +# . + +from django.contrib import admin + +from .address import AddressAdmin, CityAdmin, CountryAdmin +from .subject import SubjectAdmin + +from ..models import Address, City, Country, Subject + + +admin.site.register(Address, AddressAdmin) +admin.site.register(City, CityAdmin) +admin.site.register(Country, CountryAdmin) +admin.site.register(Subject, SubjectAdmin) diff --git a/castellum_core/castellum_core/subject_management/admin/address.py b/castellum_core/castellum_core/subject_management/admin/address.py new file mode 100644 index 0000000000000000000000000000000000000000..37f6f946df1af72ba3643ef83aef56303ec45148 --- /dev/null +++ b/castellum_core/castellum_core/subject_management/admin/address.py @@ -0,0 +1,36 @@ +# (c) 2018 +# MPIB , +# MPI-CBS , +# MPIP +# +# This file is part of Castellum. +# +# Castellum is free software; you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Castellum is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with Castellum. If not, see +# . + +from django.contrib import admin + + +class CountryAdmin(admin.ModelAdmin): + pass + + +class CityAdmin(admin.ModelAdmin): + list_display = "name", "country", + list_per_page = 200 + + +class AddressAdmin(admin.ModelAdmin): + list_display = "city", "zip_code", "street", "house_number", "additional_information" + list_per_page = 200 diff --git a/castellum_core/castellum_core/subject_management/admin/subject.py b/castellum_core/castellum_core/subject_management/admin/subject.py new file mode 100644 index 0000000000000000000000000000000000000000..af60709800ad293068306a05edaece4370dd5133 --- /dev/null +++ b/castellum_core/castellum_core/subject_management/admin/subject.py @@ -0,0 +1,42 @@ +# (c) 2018 +# MPIB , +# MPI-CBS , +# MPIP +# +# This file is part of Castellum. +# +# Castellum is free software; you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Castellum is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with Castellum. If not, see +# . + +from django.contrib import admin + + +class SubjectAdmin(admin.ModelAdmin): + list_display = "first_name", "last_name", "address", "email", "phone_number" + list_display_links = "first_name", "last_name" + list_per_page = 200 + search_fields = "first_name", "last_name" + + fieldsets = ( + (None, { + "fields": ( + ("first_name", "last_name"), + "gender", + "birthday", + ), + }), + ("Contact Data", { + "fields": ("address", "email", ("phone_number", "phone_number_alternative")) + }), + ) diff --git a/castellum_core/castellum_core/subject_management/apps.py b/castellum_core/castellum_core/subject_management/apps.py new file mode 100644 index 0000000000000000000000000000000000000000..778ea66e54b5074704b29c542e5ef5d3813525b4 --- /dev/null +++ b/castellum_core/castellum_core/subject_management/apps.py @@ -0,0 +1,26 @@ +# (c) 2018 +# MPIB , +# MPI-CBS , +# MPIP +# +# This file is part of Castellum. +# +# Castellum is free software; you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Castellum is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with Castellum. If not, see +# . + +from django.apps import AppConfig + + +class SubjectManagementConfig(AppConfig): + name = 'subject_management' diff --git a/castellum_core/castellum_core/subject_management/migrations/0001_initial.py b/castellum_core/castellum_core/subject_management/migrations/0001_initial.py new file mode 100644 index 0000000000000000000000000000000000000000..7b0595c9b66d5d82ebaa8284e2513f08a5096027 --- /dev/null +++ b/castellum_core/castellum_core/subject_management/migrations/0001_initial.py @@ -0,0 +1,83 @@ +# Generated by Django 2.0.4 on 2018-05-31 11:02 + +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Address', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('zip_code', models.CharField(max_length=5)), + ('street', models.CharField(max_length=128)), + ('house_number', models.CharField(max_length=5)), + ('additional_information', models.CharField(blank=True, default='', max_length=32)), + ], + options={ + 'verbose_name_plural': 'Addresses', + 'ordering': ('city__country__name', 'city__name', 'zip_code', 'street', 'house_number', 'additional_information'), + 'verbose_name': 'Address', + }, + ), + migrations.CreateModel( + name='City', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=128)), + ], + options={ + 'verbose_name_plural': 'Cities', + 'ordering': ('country__name', 'name'), + 'verbose_name': 'City', + }, + ), + migrations.CreateModel( + name='Country', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=64, unique=True)), + ], + options={ + 'verbose_name_plural': 'Countries', + 'ordering': ('name',), + 'verbose_name': 'Country', + }, + ), + migrations.CreateModel( + name='Subject', + fields=[ + ('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), + ('first_name', models.CharField(max_length=64)), + ('last_name', models.CharField(max_length=64)), + ('gender', models.CharField(choices=[('f', 'female'), ('m', 'male')], default='f', max_length=1)), + ('birthday', models.DateField()), + ('email', models.EmailField(blank=True, default='', max_length=128)), + ('phone_number', models.CharField(blank=True, default='', max_length=32)), + ('phone_number_alternative', models.CharField(blank=True, default='', max_length=32)), + ('address', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='subject_management.Address')), + ], + ), + migrations.AddField( + model_name='city', + name='country', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='subject_management.Country'), + ), + migrations.AddField( + model_name='address', + name='city', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='subject_management.City'), + ), + migrations.AlterUniqueTogether( + name='city', + unique_together={('name', 'country')}, + ), + ] diff --git a/castellum_core/castellum_core/subject_management/migrations/0002_auto_20180607_1232.py b/castellum_core/castellum_core/subject_management/migrations/0002_auto_20180607_1232.py new file mode 100644 index 0000000000000000000000000000000000000000..24245d02d9df68d1b02dab6872cc61105187602b --- /dev/null +++ b/castellum_core/castellum_core/subject_management/migrations/0002_auto_20180607_1232.py @@ -0,0 +1,94 @@ +# Generated by Django 2.0.4 on 2018-06-07 12:32 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('subject_management', '0001_initial'), + ] + + operations = [ + migrations.AlterField( + model_name='address', + name='additional_information', + field=models.CharField(blank=True, max_length=32, verbose_name='additional information'), + ), + migrations.AlterField( + model_name='address', + name='city', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='subject_management.City', verbose_name='City'), + ), + migrations.AlterField( + model_name='address', + name='house_number', + field=models.CharField(max_length=5, verbose_name='house_number'), + ), + migrations.AlterField( + model_name='address', + name='street', + field=models.CharField(max_length=128, verbose_name='street'), + ), + migrations.AlterField( + model_name='address', + name='zip_code', + field=models.CharField(max_length=5, verbose_name='zip code'), + ), + migrations.AlterField( + model_name='city', + name='country', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='subject_management.Country', verbose_name='Country'), + ), + migrations.AlterField( + model_name='city', + name='name', + field=models.CharField(max_length=128, verbose_name='name'), + ), + migrations.AlterField( + model_name='country', + name='name', + field=models.CharField(max_length=64, unique=True, verbose_name='name'), + ), + migrations.AlterField( + model_name='subject', + name='address', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='subject_management.Address', verbose_name='Address'), + ), + migrations.AlterField( + model_name='subject', + name='birthday', + field=models.DateField(verbose_name='birthday'), + ), + migrations.AlterField( + model_name='subject', + name='email', + field=models.EmailField(blank=True, max_length=128, verbose_name='email'), + ), + migrations.AlterField( + model_name='subject', + name='first_name', + field=models.CharField(max_length=64, verbose_name='first name'), + ), + migrations.AlterField( + model_name='subject', + name='gender', + field=models.CharField(choices=[('f', 'female'), ('m', 'male'), ('*', 'diverse')], default='f', max_length=1, verbose_name='gender'), + ), + migrations.AlterField( + model_name='subject', + name='last_name', + field=models.CharField(max_length=64, verbose_name='last name'), + ), + migrations.AlterField( + model_name='subject', + name='phone_number', + field=models.CharField(blank=True, max_length=32, verbose_name='phone number'), + ), + migrations.AlterField( + model_name='subject', + name='phone_number_alternative', + field=models.CharField(blank=True, max_length=32, verbose_name='phone number alternative'), + ), + ] diff --git a/castellum_core/castellum_core/subject_management/migrations/__init__.py b/castellum_core/castellum_core/subject_management/migrations/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/castellum_core/castellum_core/subject_management/models/__init__.py b/castellum_core/castellum_core/subject_management/models/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..026d42f6e4458cbbd49449c0d45950e653e5db6e --- /dev/null +++ b/castellum_core/castellum_core/subject_management/models/__init__.py @@ -0,0 +1,26 @@ +# (c) 2018 +# MPIB , +# MPI-CBS , +# MPIP +# +# This file is part of Castellum. +# +# Castellum is free software; you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Castellum is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with Castellum. If not, see +# . + +from .address import Address, City, Country +from .subject import Subject + + +__all__ = Address, City, Country, Subject diff --git a/castellum_core/castellum_core/subject_management/models/address.py b/castellum_core/castellum_core/subject_management/models/address.py new file mode 100644 index 0000000000000000000000000000000000000000..1e1a7faee0e37eb8a88fa15cd2338d36b53a9664 --- /dev/null +++ b/castellum_core/castellum_core/subject_management/models/address.py @@ -0,0 +1,68 @@ +# (c) 2018 +# MPIB , +# MPI-CBS , +# MPIP +# +# This file is part of Castellum. +# +# Castellum is free software; you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Castellum is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with Castellum. If not, see +# . + +from django.db import models +from django.utils.translation import ugettext_lazy as _ + + +class Country(models.Model): + name = models.CharField(_("name"), max_length=64, unique=True) + + def __str__(self): + return self.name + + class Meta: + ordering = "name", + verbose_name = _("Country") + verbose_name_plural = _("Countries") + + +class City(models.Model): + name = models.CharField(_("name"), max_length=128) + country = models.ForeignKey(Country, verbose_name=_("Country"), on_delete=models.CASCADE) + + def __str__(self): + return "{}, {}".format(self.name, self.country.name) + + class Meta: + ordering = "country__name", "name" + unique_together = "name", "country" + verbose_name = _("City") + verbose_name_plural = _("Cities") + + +class Address(models.Model): + city = models.ForeignKey(City, verbose_name=_("City"), on_delete=models.CASCADE) + zip_code = models.CharField(_("zip code"), max_length=5) + street = models.CharField(_("street"), max_length=128) + house_number = models.CharField(_("house_number"), max_length=5) + additional_information = models.CharField(_("additional information"), max_length=32, + blank=True) + + def __str__(self): + street = " ".join([self.street, self.house_number, self.additional_information]).strip() + return "{} {}, {}".format(self.zip_code, self.city.name, street) + + class Meta: + ordering = ("city__country__name", "city__name", "zip_code", "street", "house_number", + "additional_information") + verbose_name = _("Address") + verbose_name_plural = _("Addresses") diff --git a/castellum_core/castellum_core/subject_management/models/subject.py b/castellum_core/castellum_core/subject_management/models/subject.py new file mode 100644 index 0000000000000000000000000000000000000000..335e9f7f361449d5b939d8e83f99319dc3f2eaed --- /dev/null +++ b/castellum_core/castellum_core/subject_management/models/subject.py @@ -0,0 +1,51 @@ +# (c) 2018 +# MPIB , +# MPI-CBS , +# MPIP +# +# This file is part of Castellum. +# +# Castellum is free software; you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Castellum is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with Castellum. If not, see +# . + +import uuid + +from django.db import models +from django.utils.translation import ugettext_lazy as _ + +from . import Address + + +class Subject(models.Model): + GENDER = ( + ("f", _("female")), + ("m", _("male")), + ("*", _("diverse")), + ) + + id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) + + first_name = models.CharField(_("first name"), max_length=64) + last_name = models.CharField(_("last name"), max_length=64) + + gender = models.CharField(_("gender"), max_length=1, choices=GENDER, default="f") + + birthday = models.DateField(_("birthday")) + + address = models.ForeignKey(Address, blank=True, null=True, verbose_name=_("Address"), + on_delete=models.SET_NULL) + email = models.EmailField(_("email"), max_length=128, blank=True) + phone_number = models.CharField(_("phone number"), max_length=32, blank=True) + phone_number_alternative = models.CharField(_("phone number alternative"), max_length=32, + blank=True) diff --git a/castellum_core/castellum_core/subject_management/routers.py b/castellum_core/castellum_core/subject_management/routers.py new file mode 100644 index 0000000000000000000000000000000000000000..d30f649470a832f715becd6bd64eca4b37d7b72f --- /dev/null +++ b/castellum_core/castellum_core/subject_management/routers.py @@ -0,0 +1,42 @@ +# (c) 2018 +# MPIB , +# MPI-CBS , +# MPIP +# +# This file is part of Castellum. +# +# Castellum is free software; you can redistribute it and/or modify it +# under the terms of the GNU Affero General Public License as published +# by the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# Castellum is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with Castellum. If not, see +# . + +APP_LABEL = "subject_management" + + +class SubjectManagementRouter: + def db_for_read(self, model, **hints): + if model._meta.app_label == APP_LABEL: + return APP_LABEL + + def db_for_write(self, model, **hints): + if model._meta.app_label == APP_LABEL: + return APP_LABEL + + def allow_relation(self, obj1, obj2, **hints): + if obj1._meta.app_label == obj2._meta.app_label and obj1._meta.app_label == APP_LABEL: + return True + + def allow_migrate(self, db, app_label, **hints): + if db == APP_LABEL: + return app_label == APP_LABEL + elif app_label == APP_LABEL: + return False diff --git a/castellum_core/tests/subject_management/models/conftest.py b/castellum_core/tests/subject_management/models/conftest.py new file mode 100644 index 0000000000000000000000000000000000000000..a1d5cb7d169cdc60349bbadbd2a298c5bed654fd --- /dev/null +++ b/castellum_core/tests/subject_management/models/conftest.py @@ -0,0 +1,19 @@ +import pytest + +from subject_management.models import Address, City, Country + + +@pytest.fixture +def country(): + return Country(name="Germany") + + +@pytest.fixture +def city(country): + return City(name="Berlin", country=country) + + +@pytest.fixture +def address(city): + return Address(city=city, zip_code="10787", street="Hardenbergplatz", house_number="8", + additional_information="") diff --git a/castellum_core/tests/subject_management/models/test_address.py b/castellum_core/tests/subject_management/models/test_address.py new file mode 100644 index 0000000000000000000000000000000000000000..4343074235506cc03a8260420ff5fcc577e5477a --- /dev/null +++ b/castellum_core/tests/subject_management/models/test_address.py @@ -0,0 +1,7 @@ +def test_str(address): + assert "10787 Berlin, Hardenbergplatz 8" == str(address) + + +def test_str_with_additional_information(address): + address.additional_information = "appartment 3" + assert "10787 Berlin, Hardenbergplatz 8 appartment 3" == str(address) diff --git a/castellum_core/tests/subject_management/models/test_city.py b/castellum_core/tests/subject_management/models/test_city.py new file mode 100644 index 0000000000000000000000000000000000000000..7d137b2f145d32653bd9753de258a644d6c1ed88 --- /dev/null +++ b/castellum_core/tests/subject_management/models/test_city.py @@ -0,0 +1,2 @@ +def test_str(city): + assert "Berlin, Germany" == str(city) diff --git a/castellum_core/tests/subject_management/models/test_country.py b/castellum_core/tests/subject_management/models/test_country.py new file mode 100644 index 0000000000000000000000000000000000000000..81ecc6724c0a01bce9bedcbc0a40e0580b02706a --- /dev/null +++ b/castellum_core/tests/subject_management/models/test_country.py @@ -0,0 +1,2 @@ +def test_str(country): + assert "Germany" == str(country) diff --git a/castellum_core/tests/subject_management/test_router.py b/castellum_core/tests/subject_management/test_router.py new file mode 100644 index 0000000000000000000000000000000000000000..909103125d93778e5cc36cf5d697126e1d5ee122 --- /dev/null +++ b/castellum_core/tests/subject_management/test_router.py @@ -0,0 +1,48 @@ +import pytest + +from model_mommy import mommy + +from castellum_auth.models import User +from subject_management.models import Subject +from subject_management.routers import APP_LABEL, SubjectManagementRouter + + +@pytest.fixture +def router(): + return SubjectManagementRouter() + + +@pytest.mark.parametrize("model,expected", [ + (Subject, "subject_management"), + (User, None), +]) +def test_db_for_read(router, model, expected): + assert expected == router.db_for_read(model) + + +@pytest.mark.parametrize("model,expected", [ + (Subject, "subject_management"), + (User, None), +]) +def test_db_for_write(router, model, expected): + assert expected == router.db_for_write(model) + + +@pytest.mark.parametrize("obj1,obj2,expected", [ + (mommy.prepare(Subject), mommy.prepare(Subject), True), + (mommy.prepare(Subject), mommy.prepare(User), None), + (mommy.prepare(User), mommy.prepare(Subject), None), + (mommy.prepare(User), mommy.prepare(User), None), +]) +def test_allow_relation(router, obj1, obj2, expected): + assert expected == router.allow_relation(obj1, obj2) + + +@pytest.mark.parametrize("db,app_label,expected", [ + (APP_LABEL, APP_LABEL, True), + ("default", APP_LABEL, False), + (APP_LABEL, "admin", False), + ("default", "admin", None), +]) +def test_allow_migrate(router, db, app_label, expected): + assert expected == router.allow_migrate(db, app_label) diff --git a/example_deployment/settings.py b/example_deployment/settings.py index cfdfa29422931eba8cffd1fb80bd567abf461a23..2ddc3429be387be1cf666269e8b76ecfeb9bd619 100644 --- a/example_deployment/settings.py +++ b/example_deployment/settings.py @@ -15,6 +15,12 @@ DATABASES = { 'NAME': 'postgres', 'USER': 'postgres', 'HOST': 'db', + }, + 'subject_management': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': 'postgres', + 'USER': 'postgres', + 'HOST': 'db', } }