From 5a87cb294fe24263b9b6b97be807fbe5cbad469d Mon Sep 17 00:00:00 2001 From: Samuel Therrien Date: Tue, 1 Oct 2024 13:45:25 -0400 Subject: [PATCH 1/8] Add django migration test --- ...yml => canopeum_backend_pr_validation.yml} | 19 +++++++++++-- ...ml => canopeum_frontend_pr_validation.yml} | 6 ++-- canopeum_backend/canopeum_backend/settings.py | 28 ++++++++++++------- canopeum_backend/test.py | 21 ++++++++++++++ 4 files changed, 58 insertions(+), 16 deletions(-) rename .github/workflows/{canopeum_backend.yml => canopeum_backend_pr_validation.yml} (69%) rename .github/workflows/{canopeum_frontend.yml => canopeum_frontend_pr_validation.yml} (80%) create mode 100644 canopeum_backend/test.py diff --git a/.github/workflows/canopeum_backend.yml b/.github/workflows/canopeum_backend_pr_validation.yml similarity index 69% rename from .github/workflows/canopeum_backend.yml rename to .github/workflows/canopeum_backend_pr_validation.yml index 998dcd612..10fe0e073 100644 --- a/.github/workflows/canopeum_backend.yml +++ b/.github/workflows/canopeum_backend_pr_validation.yml @@ -1,4 +1,4 @@ -name: canopeum_backend +name: Backend PR validation on: push: @@ -6,14 +6,14 @@ on: - main paths: - "canopeum_backend/**" - - ".github/workflows/canopeum_backend.yml" + - ".github/workflows/canopeum_backend_pr_validation.yml" pull_request: branches: - main - production paths: - "canopeum_backend/**" - - ".github/workflows/canopeum_backend.yml" + - ".github/workflows/canopeum_backend_pr_validation.yml" env: # Since the Django mypy extention RUNS the config file, we need a non-empty secret to avoid @@ -21,6 +21,19 @@ env: SECRET_KEY_DJANGO_CANOPEUM: mypy-ext jobs: + django-test: + runs-on: ubuntu-latest + defaults: + run: + working-directory: canopeum_backend + steps: + - uses: actions/checkout@v4 + - name: Install uv using the standalone installer + run: curl -LsSf https://astral.sh/uv/install.sh | sh + - run: uv sync --locked --extra dev + - run: echo "$PWD/.venv/bin" >> $GITHUB_PATH + - name: Run Django Tests + run: python manage.py test mypy: runs-on: ubuntu-latest defaults: diff --git a/.github/workflows/canopeum_frontend.yml b/.github/workflows/canopeum_frontend_pr_validation.yml similarity index 80% rename from .github/workflows/canopeum_frontend.yml rename to .github/workflows/canopeum_frontend_pr_validation.yml index d76ffa34f..e3563610e 100644 --- a/.github/workflows/canopeum_frontend.yml +++ b/.github/workflows/canopeum_frontend_pr_validation.yml @@ -1,4 +1,4 @@ -name: canopeum_frontend +name: Frontend PR validation on: push: @@ -6,14 +6,14 @@ on: - main paths: - "canopeum_frontend/**" - - ".github/workflows/canopeum_frontend.yml" + - ".github/workflows/canopeum_frontend_pr_validation.yml" pull_request: branches: - main - production paths: - "canopeum_frontend/**" - - ".github/workflows/canopeum_frontend.yml" + - ".github/workflows/canopeum_frontend_pr_validation.yml" jobs: Lint: diff --git a/canopeum_backend/canopeum_backend/settings.py b/canopeum_backend/canopeum_backend/settings.py index 51b55f053..346616b36 100644 --- a/canopeum_backend/canopeum_backend/settings.py +++ b/canopeum_backend/canopeum_backend/settings.py @@ -11,6 +11,7 @@ """ import os +import sys from datetime import timedelta from pathlib import Path @@ -170,17 +171,24 @@ def get_secret(key: str, default: str): # Database # https://docs.djangoproject.com/en/5.0/ref/settings/#databases - DATABASES = { - "default": dj_database_url.parse( - "mysql://canopeum_user:{}@{}:{}/canopeum_db".format( - get_secret("MYSQL_PASSWORD_CANOPEUM", ""), - get_secret("MYSQL_HOST_CANOPEUM", "localhost"), - get_secret("MYSQL_PORT_CANOPEUM", "3308"), - ), - conn_max_age=600, - conn_health_checks=True, - ) + "default": ( + # If running Django tests, use an in-memory database, + # which is faster and requires less setup + # Using conditional instead of TEST dictionary because USER can't be overriden + # https://docs.djangoproject.com/en/5.1/topics/testing/overview/#the-test-database + {"ENGINE": "django.db.backends.sqlite3", "NAME": ":memory:"} + if sys.argv[1] == "test" + else dj_database_url.parse( + "mysql://canopeum_user:{}@{}:{}/canopeum_db".format( + get_secret("MYSQL_PASSWORD_CANOPEUM", ""), + get_secret("MYSQL_HOST_CANOPEUM", "localhost"), + get_secret("MYSQL_PORT_CANOPEUM", "3308"), + ), + conn_max_age=600, + conn_health_checks=True, + ) + ), } # Password validation diff --git a/canopeum_backend/test.py b/canopeum_backend/test.py new file mode 100644 index 000000000..ff81fdd16 --- /dev/null +++ b/canopeum_backend/test.py @@ -0,0 +1,21 @@ +# This should preferably go in a test folder. But we only have a single test for now +# Tests are auto-discovered as long as they're named test*.py +from io import StringIO + +from django.core.management import call_command +from django.test import TestCase as DBTestCase + + +class PendingMigrationsTests(DBTestCase): + def test_no_pending_migrations(self): + out = StringIO() + try: + # https://docs.djangoproject.com/en/5.1/ref/django-admin/#cmdoption-makemigrations-check + call_command( + "makemigrations", + "--check", + stdout=out, + stderr=StringIO(), + ) + except SystemExit: + raise AssertionError("Pending migrations:\n" + out.getvalue()) from None From 2049954aa5f17e2750e54e3565755b1b5bc1b6bd Mon Sep 17 00:00:00 2001 From: Samuel Therrien Date: Tue, 1 Oct 2024 14:05:48 -0400 Subject: [PATCH 2/8] Add TranslatableModelMixin --- canopeum_backend/canopeum_backend/models.py | 24 ++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/canopeum_backend/canopeum_backend/models.py b/canopeum_backend/canopeum_backend/models.py index 56f667d28..6c9f10226 100644 --- a/canopeum_backend/canopeum_backend/models.py +++ b/canopeum_backend/canopeum_backend/models.py @@ -21,6 +21,14 @@ gmaps = googlemaps.Client(key=GOOGLE_API_KEY) if GOOGLE_API_KEY else None +class TranslatableModelMixin(models.Model): + en = models.TextField(db_column="EN", blank=True, null=True) + fr = models.TextField(db_column="FR", blank=True, null=True) + + class Meta: + abstract = True + + class RoleName(models.TextChoices): USER = "User" SITEMANAGER = "SiteManager" @@ -126,9 +134,7 @@ def from_dms_lat_long(cls, dms_latitude: str, dms_longitude: str): ) -class SitetypeInternationalization(models.Model): - en = models.TextField(db_column="EN", blank=True, null=True) - fr = models.TextField(db_column="FR", blank=True, null=True) +class SitetypeInternationalization(TranslatableModelMixin): ... class Sitetype(models.Model): @@ -219,9 +225,7 @@ def add_supported_specie_by_id(self, pk: int): return BatchSupportedSpecies.objects.create(tree_type=tree_type, batch=self) -class FertilizertypeInternationalization(models.Model): - en = models.TextField(db_column="EN", blank=True, null=True) - fr = models.TextField(db_column="FR", blank=True, null=True) +class FertilizertypeInternationalization(TranslatableModelMixin): ... class Fertilizertype(models.Model): @@ -263,9 +267,7 @@ class Meta: ) -class TreespeciestypeInternationalization(models.Model): - en = models.TextField(db_column="EN", blank=True, null=True) - fr = models.TextField(db_column="FR", blank=True, null=True) +class TreespeciestypeInternationalization(TranslatableModelMixin): ... class Treetype(models.Model): @@ -385,9 +387,7 @@ class Like(models.Model): post = models.ForeignKey(Post, models.CASCADE) -class Internationalization(models.Model): - en = models.TextField(db_column="EN", blank=True, null=True) - fr = models.TextField(db_column="FR", blank=True, null=True) +class Internationalization(TranslatableModelMixin): ... # Everything under here are type overrides From 4b8984b13de93feaae1f216affd51f38221b2122 Mon Sep 17 00:00:00 2001 From: Samuel Therrien Date: Thu, 3 Oct 2024 15:00:14 -0400 Subject: [PATCH 3/8] Simplify translatable models and serializers --- .../commands/initialize_database.py | 33 +++------ ...name_alter_mulchlayertype_name_and_more.py | 62 ++++++++++++++++ canopeum_backend/canopeum_backend/models.py | 36 ++-------- .../canopeum_backend/serializers.py | 72 +++++++------------ 4 files changed, 102 insertions(+), 101 deletions(-) create mode 100644 canopeum_backend/canopeum_backend/migrations/0002_alter_fertilizertype_name_alter_mulchlayertype_name_and_more.py diff --git a/canopeum_backend/canopeum_backend/management/commands/initialize_database.py b/canopeum_backend/canopeum_backend/management/commands/initialize_database.py index 93105ede8..4d140e22b 100644 --- a/canopeum_backend/canopeum_backend/management/commands/initialize_database.py +++ b/canopeum_backend/canopeum_backend/management/commands/initialize_database.py @@ -22,16 +22,13 @@ Contact, Coordinate, Fertilizertype, - FertilizertypeInternationalization, + Internationalization, Mulchlayertype, - MulchlayertypeInternationalization, Post, Role, Site, Siteadmin, Sitetype, - SitetypeInternationalization, - TreespeciestypeInternationalization, Treetype, User, ) @@ -381,7 +378,7 @@ def create_fertilizer_types(self): ] for _ in fertilizer_types: Fertilizertype.objects.create( - name=FertilizertypeInternationalization.objects.create(en=_[0], fr=_[1]) + name=Internationalization.objects.create(en=_[0], fr=_[1]) ) def create_mulch_layer_types(self): @@ -395,14 +392,12 @@ def create_mulch_layer_types(self): ] for _ in mulch_layer_types: Mulchlayertype.objects.create( - name=MulchlayertypeInternationalization.objects.create(en=_[0], fr=_[1]) + name=Internationalization.objects.create(en=_[0], fr=_[1]) ) def create_tree_types(self): for _ in tree_types: - Treetype.objects.create( - name=TreespeciestypeInternationalization.objects.create(en=_[0], fr=_[1]) - ) + Treetype.objects.create(name=Internationalization.objects.create(en=_[0], fr=_[1])) def create_site_types(self): site_types = [ @@ -414,9 +409,7 @@ def create_site_types(self): ] for _ in site_types: - Sitetype.objects.create( - name=SitetypeInternationalization.objects.create(en=_[0], fr=_[1]) - ) + Sitetype.objects.create(name=Internationalization.objects.create(en=_[0], fr=_[1])) def create_assets(self): image_file_names = ( @@ -483,9 +476,7 @@ def create_canopeum_site(self): site = Site.objects.create( name="Canopeum", is_public=True, - site_type=Sitetype.objects.get( - name=SitetypeInternationalization.objects.get(en="Parks") - ), + site_type=Sitetype.objects.get(name=Internationalization.objects.get(en="Parks")), coordinate=Coordinate.objects.create( dms_latitude="45°30'06.1\"N", dms_longitude="73°34'02.3\"W", @@ -535,9 +526,7 @@ def create_other_sites(self): site_2 = Site.objects.create( name="Maple Grove Retreat", is_public=True, - site_type=Sitetype.objects.get( - name=SitetypeInternationalization.objects.get(en="Parks") - ), + site_type=Sitetype.objects.get(name=Internationalization.objects.get(en="Parks")), coordinate=Coordinate.objects.create( dms_latitude="46°48'33.6\"N", dms_longitude="71°18'40.0\"W", @@ -570,9 +559,7 @@ def create_other_sites(self): site_3 = Site.objects.create( name="Lakeside Oasis", is_public=True, - site_type=Sitetype.objects.get( - name=SitetypeInternationalization.objects.get(en="Parks") - ), + site_type=Sitetype.objects.get(name=Internationalization.objects.get(en="Parks")), coordinate=Coordinate.objects.create( dms_latitude="48°36'05.0\"N", dms_longitude="71°18'27.0\"W", @@ -606,9 +593,7 @@ def create_other_sites(self): site_4 = Site.objects.create( name="Evergreen Trail", is_public=False, - site_type=Sitetype.objects.get( - name=SitetypeInternationalization.objects.get(en="Parks") - ), + site_type=Sitetype.objects.get(name=Internationalization.objects.get(en="Parks")), coordinate=Coordinate.objects.create( dms_latitude="46°12'30.0\"N", dms_longitude="74°35'30.0\"W", diff --git a/canopeum_backend/canopeum_backend/migrations/0002_alter_fertilizertype_name_alter_mulchlayertype_name_and_more.py b/canopeum_backend/canopeum_backend/migrations/0002_alter_fertilizertype_name_alter_mulchlayertype_name_and_more.py new file mode 100644 index 000000000..e715c15de --- /dev/null +++ b/canopeum_backend/canopeum_backend/migrations/0002_alter_fertilizertype_name_alter_mulchlayertype_name_and_more.py @@ -0,0 +1,62 @@ +# Generated by Django 5.1 on 2024-10-03 18:38 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("canopeum_backend", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="fertilizertype", + name="name", + field=models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + migrations.AlterField( + model_name="mulchlayertype", + name="name", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + migrations.AlterField( + model_name="sitetype", + name="name", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + migrations.AlterField( + model_name="treetype", + name="name", + field=models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + migrations.DeleteModel( + name="FertilizertypeInternationalization", + ), + migrations.DeleteModel( + name="MulchlayertypeInternationalization", + ), + migrations.DeleteModel( + name="SitetypeInternationalization", + ), + migrations.DeleteModel( + name="TreespeciestypeInternationalization", + ), + ] diff --git a/canopeum_backend/canopeum_backend/models.py b/canopeum_backend/canopeum_backend/models.py index 6c9f10226..420b928d5 100644 --- a/canopeum_backend/canopeum_backend/models.py +++ b/canopeum_backend/canopeum_backend/models.py @@ -21,14 +21,6 @@ gmaps = googlemaps.Client(key=GOOGLE_API_KEY) if GOOGLE_API_KEY else None -class TranslatableModelMixin(models.Model): - en = models.TextField(db_column="EN", blank=True, null=True) - fr = models.TextField(db_column="FR", blank=True, null=True) - - class Meta: - abstract = True - - class RoleName(models.TextChoices): USER = "User" SITEMANAGER = "SiteManager" @@ -134,11 +126,13 @@ def from_dms_lat_long(cls, dms_latitude: str, dms_longitude: str): ) -class SitetypeInternationalization(TranslatableModelMixin): ... +class Internationalization(models.Model): + en = models.TextField(db_column="EN", blank=True, null=True) + fr = models.TextField(db_column="FR", blank=True, null=True) class Sitetype(models.Model): - name = models.ForeignKey(SitetypeInternationalization, models.DO_NOTHING, blank=True, null=True) + name = models.ForeignKey(Internationalization, models.DO_NOTHING, blank=True, null=True) @override def delete(self, using=None, keep_parents=False): @@ -225,11 +219,8 @@ def add_supported_specie_by_id(self, pk: int): return BatchSupportedSpecies.objects.create(tree_type=tree_type, batch=self) -class FertilizertypeInternationalization(TranslatableModelMixin): ... - - class Fertilizertype(models.Model): - name = models.ForeignKey(FertilizertypeInternationalization, models.DO_NOTHING) + name = models.ForeignKey(Internationalization, models.DO_NOTHING) class Batchfertilizer(models.Model): @@ -244,15 +235,8 @@ class Meta: ) -class MulchlayertypeInternationalization(models.Model): - en = models.TextField(db_column="EN", blank=True, null=True) - fr = models.TextField(db_column="FR", blank=True, null=True) - - class Mulchlayertype(models.Model): - name = models.ForeignKey( - MulchlayertypeInternationalization, models.DO_NOTHING, blank=True, null=True - ) + name = models.ForeignKey(Internationalization, models.DO_NOTHING, blank=True, null=True) class Batchmulchlayer(models.Model): @@ -267,11 +251,8 @@ class Meta: ) -class TreespeciestypeInternationalization(TranslatableModelMixin): ... - - class Treetype(models.Model): - name = models.ForeignKey(TreespeciestypeInternationalization, models.DO_NOTHING) + name = models.ForeignKey(Internationalization, models.DO_NOTHING) class BatchSpecies(models.Model): @@ -387,9 +368,6 @@ class Like(models.Model): post = models.ForeignKey(Post, models.CASCADE) -class Internationalization(TranslatableModelMixin): ... - - # Everything under here are type overrides diff --git a/canopeum_backend/canopeum_backend/serializers.py b/canopeum_backend/canopeum_backend/serializers.py index a1f96cbcc..348e922b5 100644 --- a/canopeum_backend/canopeum_backend/serializers.py +++ b/canopeum_backend/canopeum_backend/serializers.py @@ -4,9 +4,10 @@ import random from collections.abc import Mapping from decimal import Decimal -from typing import Any +from typing import Any, TypeVar from django.contrib.auth.password_validation import validate_password +from django.db import models from drf_spectacular.utils import extend_schema_field from rest_framework import serializers from rest_framework.validators import UniqueValidator @@ -44,6 +45,8 @@ ) from .utils.weather_service import get_weather_data +_ModelT = TypeVar("_ModelT", bound=models.Model) + class IntegerListFieldSerializer(serializers.ListField): child = serializers.IntegerField() @@ -186,64 +189,44 @@ class Meta: fields = ("en", "fr") -class SiteTypeSerializer(serializers.ModelSerializer[Sitetype]): +class TranslatableSerializerMixin(serializers.Serializer[_ModelT]): en = serializers.SerializerMethodField() fr = serializers.SerializerMethodField() + __translate_key__ = "name" class Meta: - model = Sitetype - fields = ("id", "en", "fr") + abstract = True + fields = ("en", "fr") def get_en(self, obj): - return InternationalizationSerializer(obj.name).data.get("en", None) + return InternationalizationSerializer(getattr(obj, self.__translate_key__)).data.get("en") def get_fr(self, obj): - return InternationalizationSerializer(obj.name).data.get("fr", None) + return InternationalizationSerializer(getattr(obj, self.__translate_key__)).data.get("fr") -class TreeTypeSerializer(serializers.ModelSerializer[Treetype]): - en = serializers.SerializerMethodField() - fr = serializers.SerializerMethodField() - +class SiteTypeSerializer(TranslatableSerializerMixin[Sitetype]): class Meta: - model = Treetype - fields = ("id", "en", "fr") - - def get_en(self, obj): - return InternationalizationSerializer(obj.name).data.get("en", None) + model = Sitetype + fields = ("id", *TranslatableSerializerMixin.Meta.fields) - def get_fr(self, obj): - return InternationalizationSerializer(obj.name).data.get("fr", None) +class TreeTypeSerializer(TranslatableSerializerMixin[Treetype]): + class Meta: + model = Treetype + fields = ("id", *TranslatableSerializerMixin.Meta.fields) -class FertilizerTypeSerializer(serializers.ModelSerializer[Fertilizertype]): - en = serializers.SerializerMethodField() - fr = serializers.SerializerMethodField() +class FertilizerTypeSerializer(TranslatableSerializerMixin[Fertilizertype]): class Meta: model = Fertilizertype - fields = ("id", "en", "fr") - - def get_en(self, obj: Fertilizertype): - return InternationalizationSerializer(obj.name).data.get("en", None) + fields = ("id", *TranslatableSerializerMixin.Meta.fields) - def get_fr(self, obj: Fertilizertype): - return InternationalizationSerializer(obj.name).data.get("fr", None) - - -class MulchLayerTypeSerializer(serializers.ModelSerializer[Mulchlayertype]): - en = serializers.SerializerMethodField() - fr = serializers.SerializerMethodField() +class MulchLayerTypeSerializer(TranslatableSerializerMixin[Mulchlayertype]): class Meta: model = Mulchlayertype - fields = ("id", "en", "fr") - - def get_en(self, obj: Mulchlayertype): - return InternationalizationSerializer(obj.name).data.get("en", None) - - def get_fr(self, obj: Mulchlayertype): - return InternationalizationSerializer(obj.name).data.get("fr", None) + fields = ("id", *TranslatableSerializerMixin.Meta.fields) class AnnouncementSerializer(serializers.ModelSerializer[Announcement]): @@ -258,24 +241,17 @@ class Meta: fields = "__all__" -class SitetreespeciesSerializer(serializers.ModelSerializer[Sitetreespecies]): - en = serializers.SerializerMethodField() - fr = serializers.SerializerMethodField() +class SitetreespeciesSerializer(TranslatableSerializerMixin[Sitetreespecies]): id = serializers.SerializerMethodField() + __translate_key__ = "tree_type" class Meta: model = Sitetreespecies - fields = ("id", "quantity", "en", "fr") + fields = ("id", "quantity", *TranslatableSerializerMixin.Meta.fields) def get_id(self, obj) -> int: return TreeTypeSerializer(obj.tree_type).data.get("id", None) # type: ignore[no-any-return] - def get_en(self, obj): - return TreeTypeSerializer(obj.tree_type).data.get("en", None) - - def get_fr(self, obj): - return TreeTypeSerializer(obj.tree_type).data.get("fr", None) - class AssetSerializer(serializers.ModelSerializer[Asset]): asset = serializers.FileField() From 5f7f27bcef027dee1c954f8ce418c7b5c763f650 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 3 Oct 2024 19:00:43 +0000 Subject: [PATCH 4/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- ...name_alter_mulchlayertype_name_and_more.py | 124 +++++++++--------- 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/canopeum_backend/canopeum_backend/migrations/0002_alter_fertilizertype_name_alter_mulchlayertype_name_and_more.py b/canopeum_backend/canopeum_backend/migrations/0002_alter_fertilizertype_name_alter_mulchlayertype_name_and_more.py index e715c15de..87736ed08 100644 --- a/canopeum_backend/canopeum_backend/migrations/0002_alter_fertilizertype_name_alter_mulchlayertype_name_and_more.py +++ b/canopeum_backend/canopeum_backend/migrations/0002_alter_fertilizertype_name_alter_mulchlayertype_name_and_more.py @@ -1,62 +1,62 @@ -# Generated by Django 5.1 on 2024-10-03 18:38 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("canopeum_backend", "0001_initial"), - ] - - operations = [ - migrations.AlterField( - model_name="fertilizertype", - name="name", - field=models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.internationalization", - ), - ), - migrations.AlterField( - model_name="mulchlayertype", - name="name", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.internationalization", - ), - ), - migrations.AlterField( - model_name="sitetype", - name="name", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.internationalization", - ), - ), - migrations.AlterField( - model_name="treetype", - name="name", - field=models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.internationalization", - ), - ), - migrations.DeleteModel( - name="FertilizertypeInternationalization", - ), - migrations.DeleteModel( - name="MulchlayertypeInternationalization", - ), - migrations.DeleteModel( - name="SitetypeInternationalization", - ), - migrations.DeleteModel( - name="TreespeciestypeInternationalization", - ), - ] +# Generated by Django 5.1 on 2024-10-03 18:38 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("canopeum_backend", "0001_initial"), + ] + + operations = [ + migrations.AlterField( + model_name="fertilizertype", + name="name", + field=models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + migrations.AlterField( + model_name="mulchlayertype", + name="name", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + migrations.AlterField( + model_name="sitetype", + name="name", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + migrations.AlterField( + model_name="treetype", + name="name", + field=models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + migrations.DeleteModel( + name="FertilizertypeInternationalization", + ), + migrations.DeleteModel( + name="MulchlayertypeInternationalization", + ), + migrations.DeleteModel( + name="SitetypeInternationalization", + ), + migrations.DeleteModel( + name="TreespeciestypeInternationalization", + ), + ] From 6ab94edce21c5f9a246ce6032062c32a83d048cf Mon Sep 17 00:00:00 2001 From: Samuel Therrien Date: Thu, 3 Oct 2024 15:19:01 -0400 Subject: [PATCH 5/8] Fix typing issue --- .../canopeum_backend/serializers.py | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/canopeum_backend/canopeum_backend/serializers.py b/canopeum_backend/canopeum_backend/serializers.py index 348e922b5..3c6aa39cb 100644 --- a/canopeum_backend/canopeum_backend/serializers.py +++ b/canopeum_backend/canopeum_backend/serializers.py @@ -4,10 +4,9 @@ import random from collections.abc import Mapping from decimal import Decimal -from typing import Any, TypeVar +from typing import Any from django.contrib.auth.password_validation import validate_password -from django.db import models from drf_spectacular.utils import extend_schema_field from rest_framework import serializers from rest_framework.validators import UniqueValidator @@ -45,8 +44,6 @@ ) from .utils.weather_service import get_weather_data -_ModelT = TypeVar("_ModelT", bound=models.Model) - class IntegerListFieldSerializer(serializers.ListField): child = serializers.IntegerField() @@ -189,7 +186,8 @@ class Meta: fields = ("en", "fr") -class TranslatableSerializerMixin(serializers.Serializer[_ModelT]): +# Note about Any: Generic is the type of "instance", not set here +class TranslatableSerializerMixin(serializers.Serializer[Any]): en = serializers.SerializerMethodField() fr = serializers.SerializerMethodField() __translate_key__ = "name" @@ -205,25 +203,29 @@ def get_fr(self, obj): return InternationalizationSerializer(getattr(obj, self.__translate_key__)).data.get("fr") -class SiteTypeSerializer(TranslatableSerializerMixin[Sitetype]): +class SiteTypeSerializer(serializers.ModelSerializer[Sitetype], TranslatableSerializerMixin): class Meta: model = Sitetype fields = ("id", *TranslatableSerializerMixin.Meta.fields) -class TreeTypeSerializer(TranslatableSerializerMixin[Treetype]): +class TreeTypeSerializer(serializers.ModelSerializer[Treetype], TranslatableSerializerMixin): class Meta: model = Treetype fields = ("id", *TranslatableSerializerMixin.Meta.fields) -class FertilizerTypeSerializer(TranslatableSerializerMixin[Fertilizertype]): +class FertilizerTypeSerializer( + serializers.ModelSerializer[Fertilizertype], TranslatableSerializerMixin +): class Meta: model = Fertilizertype fields = ("id", *TranslatableSerializerMixin.Meta.fields) -class MulchLayerTypeSerializer(TranslatableSerializerMixin[Mulchlayertype]): +class MulchLayerTypeSerializer( + serializers.ModelSerializer[Mulchlayertype], TranslatableSerializerMixin +): class Meta: model = Mulchlayertype fields = ("id", *TranslatableSerializerMixin.Meta.fields) @@ -241,7 +243,9 @@ class Meta: fields = "__all__" -class SitetreespeciesSerializer(TranslatableSerializerMixin[Sitetreespecies]): +class SitetreespeciesSerializer( + serializers.ModelSerializer[Sitetreespecies], TranslatableSerializerMixin +): id = serializers.SerializerMethodField() __translate_key__ = "tree_type" From 7c3ada0675f2d0e73ed94cfa7e2d9c3e3bc26947 Mon Sep 17 00:00:00 2001 From: Samuel Therrien Date: Tue, 22 Oct 2024 15:29:58 -0400 Subject: [PATCH 6/8] Update some init code --- .../commands/initialize_database.py | 296 +++++++++--------- canopeum_backend/uv.lock | 44 +-- 2 files changed, 172 insertions(+), 168 deletions(-) diff --git a/canopeum_backend/canopeum_backend/management/commands/initialize_database.py b/canopeum_backend/canopeum_backend/management/commands/initialize_database.py index 2c94d3727..da47fdd4e 100644 --- a/canopeum_backend/canopeum_backend/management/commands/initialize_database.py +++ b/canopeum_backend/canopeum_backend/management/commands/initialize_database.py @@ -39,105 +39,105 @@ Path(canopeum_backend.settings.BASE_DIR) / "canopeum_backend" / "seeding" / "images" ) -tree_types = [ - ["Balsam Fir", "Sapin baumier"], - ["Black Maple", "Érable noir"], - ["Red Maple", "Érable rouge"], - ["Silver Maple", "Érable argenté"], - ["Sugar Maple", "Érable à sucre"], - ["Ohio Buckeye", "Marronnier d'Ohio"], - ["Speckled Alder", "Aulne tacheté"], - ["Green Alder", "Aulne vert"], - ["Serviceberries", "Amélanchier"], - ["Black Chokeberry", "Aronie noire"], - ["Yellow Birch", "Bouleau jaune"], - ["White Birch", "Bouleau blanc"], - ["Gray Birch", "Bouleau gris"], - ["Blue Beech", "Hêtre bleu"], - ["Bitternut Hickory", "Noyer amer"], - ["Pignut Hickory", "Noyer des montagnes"], - ["Big Shellbark Hickory", "Noyer à gros fruits"], - ["Shagbark Hickory", "Noyer à écorce shaggy"], - ["American Bittersweet", "Morelle d'Amérique"], - ["Northern Hackberry", "Micocoulier occidental"], - ["Buttonbush", "Céphalanthère occidentale"], - ["Redbud", "Gainier de Virginie"], - ["Alternate-leaf Dogwood", "Cornouiller à feuilles alternes"], - ["Silky Dogwood", "Cornouiller soyeux"], - ["Flowering Dogwood", "Cornouiller à fleurs"], - ["Gray Dogwood", "Cornouiller gris"], - ["Redosier Dogwood", "Cornouiller stolonifère"], - ["American Hazelnut", "Noisetier d'Amérique"], - ["Beaked Hazel", "Coudrier à bec"], - ["Hawthorns", "Aubépines"], - ["Bush Honeysuckle", "Chèvrefeuille arbustif"], - ["American Beech", "Hêtre d'Amérique"], - ["White Ash", "Frêne blanc"], - ["Black Ash", "Frêne noir"], - ["Green/ Red Ash", "Frêne vert/rouge"], - ["Pumpkin Ash", "Frêne citrouille"], - ["Blue Ash", "Frêne bleu"], - ["Honey Locust", "Faux-acacia"], - ["Kentucky Coffeetree", "Gymnocladus de Kentucky"], - ["Witch-Hazel", "Hamamélis de Virginie"], - ["Winterberry", "Houx d'hiver"], - ["Butternut", "Noyer cendré"], - ["Black Walnut", "Noyer noir"], - ["Common Juniper", "Genévrier commun"], - ["Eastern Red Cedar", "Genévrier rouge de l'Est"], - ["Tamarac", "Mélèze laricin"], - ["Spicebush", "Lindera à feuilles opposées"], - ["Tulip-Tree", "Tulipier de Virginie"], - ["Cucumber-Tree", "Magnolia concombre"], - ["Sweetgale", "Myrica gale"], - ["Black Gum", "Nyssa sylvatica"], - ["Ironwood", "Ostryer de Virginie"], - ["Virginia Creeper", "Vigne vierge"], - ["Ninebark", "Physocarpe"], - ["White Spruce", "Épinette blanche"], - ["Black Spruce", "Épinette noire"], - ["Red Spruce", "Épinette rouge"], - ["Jack Pine", "Pin gris"], - ["Red Pine", "Pin rouge"], - ["Pitch Pine", "Pin rigide"], - ["Eastern White Pine", "Pin blanc de l'Est"], - ["Sycamore", "Platanus occidentalis"], - ["Eastern Cottonwood", "Peuplier baumier"], - ["Trembling Aspen", "Peuplier faux-tremble"], - ["American Plum", "Prunier d'Amérique"], - ["Pin Cherry", "Cerisier de Pennsylvanie"], - ["Black Cherry", "Cerisier noir"], - ["Eastern Choke Cherry", "Cerisier de Virginie"], - ["Hoptree", "Ptelea trifoliata"], - ["White Oak", "Chêne blanc"], - ["Swamp White Oak", "Chêne blanc des marais"], - ["Bur Oak", "Chêne bur"], - ["Chinquapin Oak", "Chêne chinkapin"], - ["Pin Oak", "Chêne à pin"], - ["Red Oak", "Chêne rouge"], - ["Shumard Oak", "Chêne de Shumard"], - ["Black Oak", "Chêne noir"], - ["Fragrant Sumac", "Sumac aromatique"], - ["Shining Sumac", "Sumac brillant"], - ["Staghorn Sumac", "Sumac vinaigrier"], - ["Purple-flowering Raspberry", "Ronce pourpre"], - ["Roses", "Roses"], - ["Willows", "Saules"], - ["Black Elderberry", "Sureau noir"], - ["Red Elderberry", "Sureau rouge"], - ["Sassafras", "Sassafras"], - ["American Mountain Ash", "Sorbier d'Amérique"], - ["Showy Mountain Ash", "Sorbier remarquable"], - ["Narrow-leaved Meadowsweet", "Reine-des-prés à feuilles étroites"], - ["Snowberry", "Symphorine"], - ["White Cedar", "Thuya occidental"], - ["Basswood", "Tilleul d'Amérique"], - ["Eastern Hemlock", "Pruche de l'Est"], - ["American Elm", "Orme d'Amérique"], - ["Slippery Elm", "Orme glissant"], - ["Nannyberry", "Viorne à feuilles de viorne"], - ["American Highbush Cranberry", "Viorne trilobée"], -] +tree_type_names = ( + ("Balsam Fir", "Sapin baumier"), + ("Black Maple", "Érable noir"), + ("Red Maple", "Érable rouge"), + ("Silver Maple", "Érable argenté"), + ("Sugar Maple", "Érable à sucre"), + ("Ohio Buckeye", "Marronnier d'Ohio"), + ("Speckled Alder", "Aulne tacheté"), + ("Green Alder", "Aulne vert"), + ("Serviceberries", "Amélanchier"), + ("Black Chokeberry", "Aronie noire"), + ("Yellow Birch", "Bouleau jaune"), + ("White Birch", "Bouleau blanc"), + ("Gray Birch", "Bouleau gris"), + ("Blue Beech", "Hêtre bleu"), + ("Bitternut Hickory", "Noyer amer"), + ("Pignut Hickory", "Noyer des montagnes"), + ("Big Shellbark Hickory", "Noyer à gros fruits"), + ("Shagbark Hickory", "Noyer à écorce shaggy"), + ("American Bittersweet", "Morelle d'Amérique"), + ("Northern Hackberry", "Micocoulier occidental"), + ("Buttonbush", "Céphalanthère occidentale"), + ("Redbud", "Gainier de Virginie"), + ("Alternate-leaf Dogwood", "Cornouiller à feuilles alternes"), + ("Silky Dogwood", "Cornouiller soyeux"), + ("Flowering Dogwood", "Cornouiller à fleurs"), + ("Gray Dogwood", "Cornouiller gris"), + ("Redosier Dogwood", "Cornouiller stolonifère"), + ("American Hazelnut", "Noisetier d'Amérique"), + ("Beaked Hazel", "Coudrier à bec"), + ("Hawthorns", "Aubépines"), + ("Bush Honeysuckle", "Chèvrefeuille arbustif"), + ("American Beech", "Hêtre d'Amérique"), + ("White Ash", "Frêne blanc"), + ("Black Ash", "Frêne noir"), + ("Green/ Red Ash", "Frêne vert/rouge"), + ("Pumpkin Ash", "Frêne citrouille"), + ("Blue Ash", "Frêne bleu"), + ("Honey Locust", "Faux-acacia"), + ("Kentucky Coffeetree", "Gymnocladus de Kentucky"), + ("Witch-Hazel", "Hamamélis de Virginie"), + ("Winterberry", "Houx d'hiver"), + ("Butternut", "Noyer cendré"), + ("Black Walnut", "Noyer noir"), + ("Common Juniper", "Genévrier commun"), + ("Eastern Red Cedar", "Genévrier rouge de l'Est"), + ("Tamarac", "Mélèze laricin"), + ("Spicebush", "Lindera à feuilles opposées"), + ("Tulip-Tree", "Tulipier de Virginie"), + ("Cucumber-Tree", "Magnolia concombre"), + ("Sweetgale", "Myrica gale"), + ("Black Gum", "Nyssa sylvatica"), + ("Ironwood", "Ostryer de Virginie"), + ("Virginia Creeper", "Vigne vierge"), + ("Ninebark", "Physocarpe"), + ("White Spruce", "Épinette blanche"), + ("Black Spruce", "Épinette noire"), + ("Red Spruce", "Épinette rouge"), + ("Jack Pine", "Pin gris"), + ("Red Pine", "Pin rouge"), + ("Pitch Pine", "Pin rigide"), + ("Eastern White Pine", "Pin blanc de l'Est"), + ("Sycamore", "Platanus occidentalis"), + ("Eastern Cottonwood", "Peuplier baumier"), + ("Trembling Aspen", "Peuplier faux-tremble"), + ("American Plum", "Prunier d'Amérique"), + ("Pin Cherry", "Cerisier de Pennsylvanie"), + ("Black Cherry", "Cerisier noir"), + ("Eastern Choke Cherry", "Cerisier de Virginie"), + ("Hoptree", "Ptelea trifoliata"), + ("White Oak", "Chêne blanc"), + ("Swamp White Oak", "Chêne blanc des marais"), + ("Bur Oak", "Chêne bur"), + ("Chinquapin Oak", "Chêne chinkapin"), + ("Pin Oak", "Chêne à pin"), + ("Red Oak", "Chêne rouge"), + ("Shumard Oak", "Chêne de Shumard"), + ("Black Oak", "Chêne noir"), + ("Fragrant Sumac", "Sumac aromatique"), + ("Shining Sumac", "Sumac brillant"), + ("Staghorn Sumac", "Sumac vinaigrier"), + ("Purple-flowering Raspberry", "Ronce pourpre"), + ("Roses", "Roses"), + ("Willows", "Saules"), + ("Black Elderberry", "Sureau noir"), + ("Red Elderberry", "Sureau rouge"), + ("Sassafras", "Sassafras"), + ("American Mountain Ash", "Sorbier d'Amérique"), + ("Showy Mountain Ash", "Sorbier remarquable"), + ("Narrow-leaved Meadowsweet", "Reine-des-prés à feuilles étroites"), + ("Snowberry", "Symphorine"), + ("White Cedar", "Thuya occidental"), + ("Basswood", "Tilleul d'Amérique"), + ("Eastern Hemlock", "Pruche de l'Est"), + ("American Elm", "Orme d'Amérique"), + ("Slippery Elm", "Orme glissant"), + ("Nannyberry", "Viorne à feuilles de viorne"), + ("American Highbush Cranberry", "Viorne trilobée"), +) def create_posts_for_site(site): @@ -165,7 +165,7 @@ def create_posts_for_site(site): def create_batch_species_for_batch(batch): num_species = random.randint(4, 8) - total_tree_types = len(tree_types) + total_tree_types = len(tree_type_names) # Ensure num_species is not greater than the total number # of tree types available to avoid an infinite loop @@ -185,7 +185,7 @@ def create_batch_species_for_batch(batch): ) -batch_names = [ +batch_names = ( "First Batch", "Second Batch", "Third Batch", @@ -194,7 +194,7 @@ def create_batch_species_for_batch(batch): "Sixth Batch", "Seventh Batch", "Eight Batch", -] +) sponsor_names = [ "Green Earth Initiative", @@ -377,60 +377,64 @@ def handle(self, *args, **kwargs): self.stdout.write(self.style.SUCCESS("Data Generated")) def create_fertilizer_types(self): - fertilizer_types = [ - ["Synthetic", "Synthétique"], - ["Inoculant", "Inoculant"], - ["Organic compost", "Compost organique"], - ["Manure", "Fumier"], - ["Bone meal", "Farine d'os"], - ["Fish emulsion", "Émulsion de poisson"], - ["Blood meal", "Farine de sang"], - ["Seaweed fertilizer", "Engrais d'algues"], - ["Bat guano", "Guano de chauve-souris"], - ["Worm castings", "Moulée de vers"], - ["Compost tea", "Thé de compost"], - ["Wood ash", "Cendre de bois"], - ["Rock phosphate", "Phosphate de roche"], - ["Greensand", "Sable vert"], - ["Alfalfa meal", "Farine d'alfalfa"], - ["Cottonseed meal", "Farine de tourteau de coton"], - ["Feather meal", "Farine de plumes"], - ["Humic acid", "Acide humique"], - ] - for _ in fertilizer_types: + fertilizer_type_names = ( + ("Synthetic", "Synthétique"), + ("Inoculant", "Inoculant"), + ("Organic compost", "Compost organique"), + ("Manure", "Fumier"), + ("Bone meal", "Farine d'os"), + ("Fish emulsion", "Émulsion de poisson"), + ("Blood meal", "Farine de sang"), + ("Seaweed fertilizer", "Engrais d'algues"), + ("Bat guano", "Guano de chauve-souris"), + ("Worm castings", "Moulée de vers"), + ("Compost tea", "Thé de compost"), + ("Wood ash", "Cendre de bois"), + ("Rock phosphate", "Phosphate de roche"), + ("Greensand", "Sable vert"), + ("Alfalfa meal", "Farine d'alfalfa"), + ("Cottonseed meal", "Farine de tourteau de coton"), + ("Feather meal", "Farine de plumes"), + ("Humic acid", "Acide humique"), + ) + for name in fertilizer_type_names: Fertilizertype.objects.create( - name=Internationalization.objects.create(en=_[0], fr=_[1]) + name=Internationalization.objects.create(en=name[0], fr=name[1]) ) def create_mulch_layer_types(self): - mulch_layer_types = [ - ["Sheep wool", "Laine de mouton"], - ["Cardboard", "Carton"], - ["Compost", "Compost"], - ["Woodchips", "Copeaux de bois"], - ["Saw dust", "Poussière de scie"], - ["Corn husk", "Feuille de maïs"], - ] - for _ in mulch_layer_types: + mulch_layer_type_names = ( + ("Sheep wool", "Laine de mouton"), + ("Cardboard", "Carton"), + ("Compost", "Compost"), + ("Woodchips", "Copeaux de bois"), + ("Saw dust", "Poussière de scie"), + ("Corn husk", "Feuille de maïs"), + ) + for name in mulch_layer_type_names: Mulchlayertype.objects.create( - name=Internationalization.objects.create(en=_[0], fr=_[1]) + name=Internationalization.objects.create(en=name[0], fr=name[1]) ) def create_tree_types(self): - for _ in tree_types: - Treetype.objects.create(name=Internationalization.objects.create(en=_[0], fr=_[1])) + for name in tree_type_names: + Treetype.objects.create( + name=Internationalization.objects.create(en=name[0], fr=name[1]) + ) def create_site_types(self): - site_types = [ - ["Parks", "Parcs"], - ["Indigenous community", "Communauté Indigène"], - ["Educational Facility", "Établissement d'enseignement"], - ["Farms Land", "Terres agricoles"], - ["Corporate Lot", "Lot d'entreprise"], - ] - - for _ in site_types: - Sitetype.objects.create(name=Internationalization.objects.create(en=_[0], fr=_[1])) + site_type_names = ( + ("Parks", "Parcs"), + ("Indigenous community", "Communauté Indigène"), + ("Educational Facility", "Établissement d'enseignement"), + ("Farms Land", "Terres agricoles"), + ("Corporate Lot", "Lot d'entreprise"), + ) + + for name in site_type_names: + Sitetype.objects.create( + name=Internationalization.objects.create(en=name[0], fr=name[1]) + ) def create_assets(self): image_file_names = ( diff --git a/canopeum_backend/uv.lock b/canopeum_backend/uv.lock index 40ecfd395..795134159 100644 --- a/canopeum_backend/uv.lock +++ b/canopeum_backend/uv.lock @@ -72,7 +72,7 @@ requires-dist = [ { name = "python-dotenv" }, { name = "requests-cache", specifier = ">=1.2.1" }, { name = "retry-requests", specifier = ">=2.0.0" }, - { name = "ruff", marker = "extra == 'dev'", specifier = "==0.5.7" }, + { name = "ruff", marker = "extra == 'dev'", specifier = "==0.6.9" }, { name = "types-jsonschema", marker = "extra == 'dev'" }, ] @@ -622,27 +622,27 @@ wheels = [ [[package]] name = "ruff" -version = "0.5.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bf/2b/69e5e412f9d390adbdbcbf4f64d6914fa61b44b08839a6584655014fc524/ruff-0.5.7.tar.gz", hash = "sha256:8dfc0a458797f5d9fb622dd0efc52d796f23f0a1493a9527f4e49a550ae9a7e5", size = 2449817 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/eb/06e06aaf96af30a68e83b357b037008c54a2ddcbad4f989535007c700394/ruff-0.5.7-py3-none-linux_armv6l.whl", hash = "sha256:548992d342fc404ee2e15a242cdbea4f8e39a52f2e7752d0e4cbe88d2d2f416a", size = 9570571 }, - { url = "https://files.pythonhosted.org/packages/a4/10/1be32aeaab8728f78f673e7a47dd813222364479b2d6573dbcf0085e83ea/ruff-0.5.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:00cc8872331055ee017c4f1071a8a31ca0809ccc0657da1d154a1d2abac5c0be", size = 8685138 }, - { url = "https://files.pythonhosted.org/packages/3d/1d/c218ce83beb4394ba04d05e9aa2ae6ce9fba8405688fe878b0fdb40ce855/ruff-0.5.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:eaf3d86a1fdac1aec8a3417a63587d93f906c678bb9ed0b796da7b59c1114a1e", size = 8266785 }, - { url = "https://files.pythonhosted.org/packages/26/79/7f49509bd844476235b40425756def366b227a9714191c91f02fb2178635/ruff-0.5.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a01c34400097b06cf8a6e61b35d6d456d5bd1ae6961542de18ec81eaf33b4cb8", size = 9983964 }, - { url = "https://files.pythonhosted.org/packages/bf/b1/939836b70bf9fcd5e5cd3ea67fdb8abb9eac7631351d32f26544034a35e4/ruff-0.5.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fcc8054f1a717e2213500edaddcf1dbb0abad40d98e1bd9d0ad364f75c763eea", size = 9359490 }, - { url = "https://files.pythonhosted.org/packages/32/7d/b3db19207de105daad0c8b704b2c6f2a011f9c07017bd58d8d6e7b8eba19/ruff-0.5.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f70284e73f36558ef51602254451e50dd6cc479f8b6f8413a95fcb5db4a55fc", size = 10170833 }, - { url = "https://files.pythonhosted.org/packages/a2/45/eae9da55f3357a1ac04220230b8b07800bf516e6dd7e1ad20a2ff3b03b1b/ruff-0.5.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a78ad870ae3c460394fc95437d43deb5c04b5c29297815a2a1de028903f19692", size = 10896360 }, - { url = "https://files.pythonhosted.org/packages/99/67/4388b36d145675f4c51ebec561fcd4298a0e2550c81e629116f83ce45a39/ruff-0.5.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ccd078c66a8e419475174bfe60a69adb36ce04f8d4e91b006f1329d5cd44bcf", size = 10477094 }, - { url = "https://files.pythonhosted.org/packages/e1/9c/f5e6ed1751dc187a4ecf19a4970dd30a521c0ee66b7941c16e292a4043fb/ruff-0.5.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7e31c9bad4ebf8fdb77b59cae75814440731060a09a0e0077d559a556453acbb", size = 11480896 }, - { url = "https://files.pythonhosted.org/packages/c8/3b/2b683be597bbd02046678fc3fc1c199c641512b20212073b58f173822bb3/ruff-0.5.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d796327eed8e168164346b769dd9a27a70e0298d667b4ecee6877ce8095ec8e", size = 10179702 }, - { url = "https://files.pythonhosted.org/packages/f1/38/c2d94054dc4b3d1ea4c2ba3439b2a7095f08d1c8184bc41e6abe2a688be7/ruff-0.5.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4a09ea2c3f7778cc635e7f6edf57d566a8ee8f485f3c4454db7771efb692c499", size = 9982855 }, - { url = "https://files.pythonhosted.org/packages/7d/e7/1433db2da505ffa8912dcf5b28a8743012ee780cbc20ad0bf114787385d9/ruff-0.5.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a36d8dcf55b3a3bc353270d544fb170d75d2dff41eba5df57b4e0b67a95bb64e", size = 9433156 }, - { url = "https://files.pythonhosted.org/packages/e0/36/4fa43250e67741edeea3d366f59a1dc993d4d89ad493a36cbaa9889895f2/ruff-0.5.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9369c218f789eefbd1b8d82a8cf25017b523ac47d96b2f531eba73770971c9e5", size = 9782971 }, - { url = "https://files.pythonhosted.org/packages/80/0e/8c276103d518e5cf9202f70630aaa494abf6fc71c04d87c08b6d3cd07a4b/ruff-0.5.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b88ca3db7eb377eb24fb7c82840546fb7acef75af4a74bd36e9ceb37a890257e", size = 10247775 }, - { url = "https://files.pythonhosted.org/packages/cb/b9/673096d61276f39291b729dddde23c831a5833d98048349835782688a0ec/ruff-0.5.7-py3-none-win32.whl", hash = "sha256:33d61fc0e902198a3e55719f4be6b375b28f860b09c281e4bdbf783c0566576a", size = 7841772 }, - { url = "https://files.pythonhosted.org/packages/67/1c/4520c98bfc06b9c73cd1457686d4d3935d40046b1ddea08403e5a6deff51/ruff-0.5.7-py3-none-win_amd64.whl", hash = "sha256:083bbcbe6fadb93cd86709037acc510f86eed5a314203079df174c40bbbca6b3", size = 8699779 }, - { url = "https://files.pythonhosted.org/packages/38/23/b3763a237d2523d40a31fe2d1a301191fe392dd48d3014977d079cf8c0bd/ruff-0.5.7-py3-none-win_arm64.whl", hash = "sha256:2dca26154ff9571995107221d0aeaad0e75a77b5a682d6236cf89a58c70b76f4", size = 8091891 }, +version = "0.6.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/0d/6148a48dab5662ca1d5a93b7c0d13c03abd3cc7e2f35db08410e47cef15d/ruff-0.6.9.tar.gz", hash = "sha256:b076ef717a8e5bc819514ee1d602bbdca5b4420ae13a9cf61a0c0a4f53a2baa2", size = 3095355 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6e/8f/f7a0a0ef1818662efb32ed6df16078c95da7a0a3248d64c2410c1e27799f/ruff-0.6.9-py3-none-linux_armv6l.whl", hash = "sha256:064df58d84ccc0ac0fcd63bc3090b251d90e2a372558c0f057c3f75ed73e1ccd", size = 10440526 }, + { url = "https://files.pythonhosted.org/packages/8b/69/b179a5faf936a9e2ab45bb412a668e4661eded964ccfa19d533f29463ef6/ruff-0.6.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:140d4b5c9f5fc7a7b074908a78ab8d384dd7f6510402267bc76c37195c02a7ec", size = 10034612 }, + { url = "https://files.pythonhosted.org/packages/c7/ef/fd1b4be979c579d191eeac37b5cfc0ec906de72c8bcd8595e2c81bb700c1/ruff-0.6.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:53fd8ca5e82bdee8da7f506d7b03a261f24cd43d090ea9db9a1dc59d9313914c", size = 9706197 }, + { url = "https://files.pythonhosted.org/packages/29/61/b376d775deb5851cb48d893c568b511a6d3625ef2c129ad5698b64fb523c/ruff-0.6.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645d7d8761f915e48a00d4ecc3686969761df69fb561dd914a773c1a8266e14e", size = 10751855 }, + { url = "https://files.pythonhosted.org/packages/13/d7/def9e5f446d75b9a9c19b24231a3a658c075d79163b08582e56fa5dcfa38/ruff-0.6.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eae02b700763e3847595b9d2891488989cac00214da7f845f4bcf2989007d577", size = 10200889 }, + { url = "https://files.pythonhosted.org/packages/6c/d6/7f34160818bcb6e84ce293a5966cba368d9112ff0289b273fbb689046047/ruff-0.6.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d5ccc9e58112441de8ad4b29dcb7a86dc25c5f770e3c06a9d57e0e5eba48829", size = 11038678 }, + { url = "https://files.pythonhosted.org/packages/13/34/a40ff8ae62fb1b26fb8e6fa7e64bc0e0a834b47317880de22edd6bfb54fb/ruff-0.6.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:417b81aa1c9b60b2f8edc463c58363075412866ae4e2b9ab0f690dc1e87ac1b5", size = 11808682 }, + { url = "https://files.pythonhosted.org/packages/2e/6d/25a4386ae4009fc798bd10ba48c942d1b0b3e459b5403028f1214b6dd161/ruff-0.6.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c866b631f5fbce896a74a6e4383407ba7507b815ccc52bcedabb6810fdb3ef7", size = 11330446 }, + { url = "https://files.pythonhosted.org/packages/f7/f6/bdf891a9200d692c94ebcd06ae5a2fa5894e522f2c66c2a12dd5d8cb2654/ruff-0.6.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7b118afbb3202f5911486ad52da86d1d52305b59e7ef2031cea3425142b97d6f", size = 12483048 }, + { url = "https://files.pythonhosted.org/packages/a7/86/96f4252f41840e325b3fa6c48297e661abb9f564bd7dcc0572398c8daa42/ruff-0.6.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67267654edc23c97335586774790cde402fb6bbdb3c2314f1fc087dee320bfa", size = 10936855 }, + { url = "https://files.pythonhosted.org/packages/45/87/801a52d26c8dbf73424238e9908b9ceac430d903c8ef35eab1b44fcfa2bd/ruff-0.6.9-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3ef0cc774b00fec123f635ce5c547dac263f6ee9fb9cc83437c5904183b55ceb", size = 10713007 }, + { url = "https://files.pythonhosted.org/packages/be/27/6f7161d90320a389695e32b6ebdbfbedde28ccbf52451e4b723d7ce744ad/ruff-0.6.9-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:12edd2af0c60fa61ff31cefb90aef4288ac4d372b4962c2864aeea3a1a2460c0", size = 10274594 }, + { url = "https://files.pythonhosted.org/packages/00/52/dc311775e7b5f5b19831563cb1572ecce63e62681bccc609867711fae317/ruff-0.6.9-py3-none-musllinux_1_2_i686.whl", hash = "sha256:55bb01caeaf3a60b2b2bba07308a02fca6ab56233302406ed5245180a05c5625", size = 10608024 }, + { url = "https://files.pythonhosted.org/packages/98/b6/be0a1ddcbac65a30c985cf7224c4fce786ba2c51e7efeb5178fe410ed3cf/ruff-0.6.9-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:925d26471fa24b0ce5a6cdfab1bb526fb4159952385f386bdcc643813d472039", size = 10982085 }, + { url = "https://files.pythonhosted.org/packages/bb/a4/c84bc13d0b573cf7bb7d17b16d6d29f84267c92d79b2f478d4ce322e8e72/ruff-0.6.9-py3-none-win32.whl", hash = "sha256:eb61ec9bdb2506cffd492e05ac40e5bc6284873aceb605503d8494180d6fc84d", size = 8522088 }, + { url = "https://files.pythonhosted.org/packages/74/be/fc352bd8ca40daae8740b54c1c3e905a7efe470d420a268cd62150248c91/ruff-0.6.9-py3-none-win_amd64.whl", hash = "sha256:785d31851c1ae91f45b3d8fe23b8ae4b5170089021fbb42402d811135f0b7117", size = 9359275 }, + { url = "https://files.pythonhosted.org/packages/3e/14/fd026bc74ded05e2351681545a5f626e78ef831f8edce064d61acd2e6ec7/ruff-0.6.9-py3-none-win_arm64.whl", hash = "sha256:a9641e31476d601f83cd602608739a0840e348bda93fec9f1ee816f8b6798b93", size = 8679879 }, ] [[package]] From bd0d6ddfaad1bfc80150deadd3bcb9428112afba Mon Sep 17 00:00:00 2001 From: Samuel Therrien Date: Tue, 22 Oct 2024 17:08:34 -0400 Subject: [PATCH 7/8] Redo initial migration --- .../migrations/0001_initial.py | 1298 ++++++++++++----- ...name_alter_mulchlayertype_name_and_more.py | 62 - 2 files changed, 937 insertions(+), 423 deletions(-) delete mode 100644 canopeum_backend/canopeum_backend/migrations/0002_alter_fertilizertype_name_alter_mulchlayertype_name_and_more.py diff --git a/canopeum_backend/canopeum_backend/migrations/0001_initial.py b/canopeum_backend/canopeum_backend/migrations/0001_initial.py index 365ee675b..182a0d10b 100644 --- a/canopeum_backend/canopeum_backend/migrations/0001_initial.py +++ b/canopeum_backend/canopeum_backend/migrations/0001_initial.py @@ -1,361 +1,937 @@ -# Generated by Django 5.1 on 2024-09-30 16:29 - -import canopeum_backend.models -import django.contrib.auth.models -import django.contrib.auth.validators -import django.db.models.deletion -import django.utils.timezone -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ('auth', '0012_alter_user_first_name_max_length'), - ] - - operations = [ - migrations.CreateModel( - name='Announcement', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('body', models.TextField(blank=True, null=True)), - ('link', models.TextField(blank=True, null=True)), - ], - ), - migrations.CreateModel( - name='Asset', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('asset', models.FileField(upload_to=canopeum_backend.models.upload_to)), - ], - ), - migrations.CreateModel( - name='Contact', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('address', models.TextField(blank=True, null=True)), - ('email', models.EmailField(blank=True, max_length=254, null=True)), - ('phone', models.CharField(blank=True, max_length=20, null=True)), - ('facebook_link', models.URLField(blank=True, null=True)), - ('x_link', models.URLField(blank=True, null=True)), - ('instagram_link', models.URLField(blank=True, null=True)), - ('linkedin_link', models.URLField(blank=True, null=True)), - ], - ), - migrations.CreateModel( - name='Coordinate', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('dms_latitude', models.TextField(blank=True, null=True)), - ('dms_longitude', models.TextField(blank=True, null=True)), - ('dd_latitude', models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True)), - ('dd_longitude', models.DecimalField(blank=True, decimal_places=6, max_digits=9, null=True)), - ('address', models.TextField(blank=True, null=True)), - ], - ), - migrations.CreateModel( - name='FertilizertypeInternationalization', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('en', models.TextField(blank=True, db_column='EN', null=True)), - ('fr', models.TextField(blank=True, db_column='FR', null=True)), - ], - ), - migrations.CreateModel( - name='Internationalization', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('en', models.TextField(blank=True, db_column='EN', null=True)), - ('fr', models.TextField(blank=True, db_column='FR', null=True)), - ], - ), - migrations.CreateModel( - name='MulchlayertypeInternationalization', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('en', models.TextField(blank=True, db_column='EN', null=True)), - ('fr', models.TextField(blank=True, db_column='FR', null=True)), - ], - ), - migrations.CreateModel( - name='Post', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('body', models.TextField()), - ('share_count', models.IntegerField(default=0)), - ('created_at', models.DateTimeField(auto_now_add=True)), - ], - ), - migrations.CreateModel( - name='Role', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(choices=[('User', 'User'), ('SiteManager', 'Sitemanager'), ('MegaAdmin', 'Megaadmin')], default='User', max_length=11)), - ], - ), - migrations.CreateModel( - name='Sitetype', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ], - ), - migrations.CreateModel( - name='SitetypeInternationalization', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('en', models.TextField(blank=True, db_column='EN', null=True)), - ('fr', models.TextField(blank=True, db_column='FR', null=True)), - ], - ), - migrations.CreateModel( - name='TreespeciestypeInternationalization', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('en', models.TextField(blank=True, db_column='EN', null=True)), - ('fr', models.TextField(blank=True, db_column='FR', null=True)), - ], - ), - migrations.CreateModel( - name='User', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('password', models.CharField(max_length=128, verbose_name='password')), - ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), - ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), - ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), - ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), - ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), - ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), - ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), - ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), - ('email', models.EmailField(max_length=255, unique=True, verbose_name='email address')), - ('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')), - ('role', models.ForeignKey(default=1, on_delete=django.db.models.deletion.RESTRICT, to='canopeum_backend.role')), - ], - options={ - 'verbose_name': 'user', - 'verbose_name_plural': 'users', - 'abstract': False, - }, - managers=[ - ('objects', django.contrib.auth.models.UserManager()), - ], - ), - migrations.CreateModel( - name='BatchSponsor', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.TextField()), - ('url', models.TextField()), - ('logo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.asset')), - ], - ), - migrations.CreateModel( - name='Fertilizertype', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='canopeum_backend.fertilizertypeinternationalization')), - ], - ), - migrations.CreateModel( - name='Mulchlayertype', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='canopeum_backend.mulchlayertypeinternationalization')), - ], - ), - migrations.CreateModel( - name='Like', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.post')), - ], - ), - migrations.CreateModel( - name='Comment', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('body', models.TextField()), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.post')), - ], - ), - migrations.CreateModel( - name='PostAsset', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('asset', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='canopeum_backend.asset')), - ('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.post')), - ], - ), - migrations.AddField( - model_name='post', - name='media', - field=models.ManyToManyField(blank=True, through='canopeum_backend.PostAsset', to='canopeum_backend.asset'), - ), - migrations.CreateModel( - name='Site', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.TextField()), - ('is_public', models.BooleanField(default=False)), - ('description', models.TextField(blank=True, null=True)), - ('size', models.TextField(blank=True, null=True)), - ('research_partnership', models.BooleanField(blank=True, null=True)), - ('visible_map', models.BooleanField(blank=True, null=True)), - ('visitor_count', models.IntegerField(blank=True, null=True)), - ('announcement', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='canopeum_backend.announcement')), - ('contact', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='canopeum_backend.contact')), - ('coordinate', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='canopeum_backend.coordinate')), - ('image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='canopeum_backend.asset')), - ('site_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='canopeum_backend.sitetype')), - ], - ), - migrations.AddField( - model_name='post', - name='site', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.site'), - ), - migrations.CreateModel( - name='Batch', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True, null=True)), - ('updated_at', models.DateTimeField(auto_now=True, null=True)), - ('name', models.TextField(blank=True, null=True)), - ('size', models.IntegerField(blank=True, null=True)), - ('soil_condition', models.TextField(blank=True, null=True)), - ('survived_count', models.IntegerField(blank=True, null=True)), - ('replace_count', models.IntegerField(blank=True, null=True)), - ('total_number_seed', models.IntegerField(blank=True, null=True)), - ('total_propagation', models.IntegerField(blank=True, null=True)), - ('image', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='canopeum_backend.asset')), - ('sponsor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.batchsponsor')), - ('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.site')), - ], - ), - migrations.CreateModel( - name='Siteadmin', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.site')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.CreateModel( - name='SiteFollower', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.site')), - ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), - ], - ), - migrations.AddField( - model_name='sitetype', - name='name', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.DO_NOTHING, to='canopeum_backend.sitetypeinternationalization'), - ), - migrations.CreateModel( - name='Treetype', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='canopeum_backend.treespeciestypeinternationalization')), - ], - ), - migrations.CreateModel( - name='UserInvitation', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('code', models.CharField(max_length=64, unique=True)), - ('expires_at', models.DateTimeField(default=canopeum_backend.models.one_week_from_today)), - ('email', models.EmailField(max_length=254)), - ('assigned_to_sites', models.ManyToManyField(to='canopeum_backend.site')), - ], - ), - migrations.CreateModel( - name='Widget', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('title', models.TextField(blank=True, null=True)), - ('body', models.TextField(blank=True, null=True)), - ('site', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.site')), - ], - ), - migrations.CreateModel( - name='Batchfertilizer', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('batch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.batch')), - ('fertilizer_type', models.ForeignKey(on_delete=django.db.models.deletion.RESTRICT, to='canopeum_backend.fertilizertype')), - ], - options={ - 'constraints': [models.UniqueConstraint(fields=('batch', 'fertilizer_type'), name='unique_fertilizer_per_batch')], - }, - ), - migrations.CreateModel( - name='Batchmulchlayer', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('batch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.batch')), - ('mulch_layer_type', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='canopeum_backend.mulchlayertype')), - ], - options={ - 'constraints': [models.UniqueConstraint(fields=('batch', 'mulch_layer_type'), name='unique_mulch_layer_per_batch')], - }, - ), - migrations.CreateModel( - name='Sitetreespecies', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('quantity', models.IntegerField()), - ('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.site')), - ('tree_type', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='canopeum_backend.treetype')), - ], - options={ - 'constraints': [models.UniqueConstraint(fields=('site', 'tree_type'), name='unique_tree_species_per_site')], - }, - ), - migrations.CreateModel( - name='BatchSupportedSpecies', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('batch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.batch')), - ('tree_type', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='canopeum_backend.treetype')), - ], - options={ - 'constraints': [models.UniqueConstraint(fields=('batch', 'tree_type'), name='unique_supported_species_per_batch')], - }, - ), - migrations.CreateModel( - name='BatchSpecies', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('quantity', models.IntegerField()), - ('batch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.batch')), - ('tree_type', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='canopeum_backend.treetype')), - ], - options={ - 'constraints': [models.UniqueConstraint(fields=('batch', 'tree_type'), name='unique_species_per_batch')], - }, - ), - migrations.CreateModel( - name='BatchSeed', - fields=[ - ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('quantity', models.IntegerField()), - ('batch', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='canopeum_backend.batch')), - ('tree_type', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='canopeum_backend.treetype')), - ], - options={ - 'constraints': [models.UniqueConstraint(fields=('batch', 'tree_type'), name='unique_seed_per_batch')], - }, - ), - ] +# Generated by Django 5.1 on 2024-10-22 21:07 + +import canopeum_backend.models +import django.contrib.auth.models +import django.contrib.auth.validators +import django.db.models.deletion +import django.utils.timezone +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ("auth", "0012_alter_user_first_name_max_length"), + ] + + operations = [ + migrations.CreateModel( + name="Announcement", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("body", models.TextField(blank=True, null=True)), + ("link", models.TextField(blank=True, null=True)), + ], + ), + migrations.CreateModel( + name="Asset", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "asset", + models.FileField(upload_to=canopeum_backend.models.upload_to), + ), + ], + ), + migrations.CreateModel( + name="Contact", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("address", models.TextField(blank=True, null=True)), + ("email", models.EmailField(blank=True, max_length=254, null=True)), + ("phone", models.CharField(blank=True, max_length=20, null=True)), + ("facebook_link", models.URLField(blank=True, null=True)), + ("x_link", models.URLField(blank=True, null=True)), + ("instagram_link", models.URLField(blank=True, null=True)), + ("linkedin_link", models.URLField(blank=True, null=True)), + ], + ), + migrations.CreateModel( + name="Coordinate", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("dms_latitude", models.TextField(blank=True, null=True)), + ("dms_longitude", models.TextField(blank=True, null=True)), + ( + "dd_latitude", + models.DecimalField( + blank=True, decimal_places=6, max_digits=9, null=True + ), + ), + ( + "dd_longitude", + models.DecimalField( + blank=True, decimal_places=6, max_digits=9, null=True + ), + ), + ("address", models.TextField(blank=True, null=True)), + ], + ), + migrations.CreateModel( + name="Internationalization", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("en", models.TextField(blank=True, db_column="EN", null=True)), + ("fr", models.TextField(blank=True, db_column="FR", null=True)), + ], + ), + migrations.CreateModel( + name="Post", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("body", models.TextField()), + ("share_count", models.IntegerField(default=0)), + ("created_at", models.DateTimeField(auto_now_add=True)), + ], + ), + migrations.CreateModel( + name="Role", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "name", + models.CharField( + choices=[ + ("User", "User"), + ("SiteManager", "Sitemanager"), + ("MegaAdmin", "Megaadmin"), + ], + default="User", + max_length=11, + ), + ), + ], + ), + migrations.CreateModel( + name="User", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("password", models.CharField(max_length=128, verbose_name="password")), + ( + "last_login", + models.DateTimeField( + blank=True, null=True, verbose_name="last login" + ), + ), + ( + "is_superuser", + models.BooleanField( + default=False, + help_text="Designates that this user has all permissions without explicitly assigning them.", + verbose_name="superuser status", + ), + ), + ( + "username", + models.CharField( + error_messages={ + "unique": "A user with that username already exists." + }, + help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.", + max_length=150, + unique=True, + validators=[ + django.contrib.auth.validators.UnicodeUsernameValidator() + ], + verbose_name="username", + ), + ), + ( + "first_name", + models.CharField( + blank=True, max_length=150, verbose_name="first name" + ), + ), + ( + "last_name", + models.CharField( + blank=True, max_length=150, verbose_name="last name" + ), + ), + ( + "is_staff", + models.BooleanField( + default=False, + help_text="Designates whether the user can log into this admin site.", + verbose_name="staff status", + ), + ), + ( + "is_active", + models.BooleanField( + default=True, + help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.", + verbose_name="active", + ), + ), + ( + "date_joined", + models.DateTimeField( + default=django.utils.timezone.now, verbose_name="date joined" + ), + ), + ( + "email", + models.EmailField( + max_length=255, unique=True, verbose_name="email address" + ), + ), + ( + "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", + ), + ), + ( + "role", + models.ForeignKey( + default=1, + on_delete=django.db.models.deletion.RESTRICT, + to="canopeum_backend.role", + ), + ), + ], + options={ + "verbose_name": "user", + "verbose_name_plural": "users", + "abstract": False, + }, + managers=[ + ("objects", django.contrib.auth.models.UserManager()), + ], + ), + migrations.CreateModel( + name="BatchSponsor", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.TextField()), + ("url", models.TextField()), + ( + "logo", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.asset", + ), + ), + ], + ), + migrations.CreateModel( + name="Fertilizertype", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "name", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + ], + ), + migrations.CreateModel( + name="Mulchlayertype", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "name", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + ], + ), + migrations.CreateModel( + name="Like", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "post", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.post", + ), + ), + ], + ), + migrations.CreateModel( + name="Comment", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("body", models.TextField()), + ("created_at", models.DateTimeField(auto_now_add=True)), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "post", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.post", + ), + ), + ], + ), + migrations.CreateModel( + name="PostAsset", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "asset", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.asset", + ), + ), + ( + "post", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.post", + ), + ), + ], + ), + migrations.AddField( + model_name="post", + name="media", + field=models.ManyToManyField( + blank=True, + through="canopeum_backend.PostAsset", + to="canopeum_backend.asset", + ), + ), + migrations.CreateModel( + name="Site", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.TextField()), + ("is_public", models.BooleanField(default=False)), + ("description", models.TextField(blank=True, null=True)), + ("size", models.TextField(blank=True, null=True)), + ("research_partnership", models.BooleanField(blank=True, null=True)), + ("visible_map", models.BooleanField(blank=True, null=True)), + ("visitor_count", models.IntegerField(blank=True, null=True)), + ( + "announcement", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="canopeum_backend.announcement", + ), + ), + ( + "contact", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="canopeum_backend.contact", + ), + ), + ( + "coordinate", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="canopeum_backend.coordinate", + ), + ), + ( + "image", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="canopeum_backend.asset", + ), + ), + ], + ), + migrations.AddField( + model_name="post", + name="site", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="canopeum_backend.site" + ), + ), + migrations.CreateModel( + name="Batch", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True, null=True)), + ("updated_at", models.DateTimeField(auto_now=True, null=True)), + ("name", models.TextField(blank=True, null=True)), + ("size", models.IntegerField(blank=True, null=True)), + ("soil_condition", models.TextField(blank=True, null=True)), + ("survived_count", models.IntegerField(blank=True, null=True)), + ("replace_count", models.IntegerField(blank=True, null=True)), + ("total_number_seed", models.IntegerField(blank=True, null=True)), + ("total_propagation", models.IntegerField(blank=True, null=True)), + ( + "image", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.asset", + ), + ), + ( + "sponsor", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.batchsponsor", + ), + ), + ( + "site", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.site", + ), + ), + ], + ), + migrations.CreateModel( + name="Siteadmin", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "site", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.site", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.CreateModel( + name="SiteFollower", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ( + "site", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.site", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.CreateModel( + name="Sitetype", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "name", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + ], + ), + migrations.AddField( + model_name="site", + name="site_type", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.sitetype", + ), + ), + migrations.CreateModel( + name="Treetype", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "name", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + ], + ), + migrations.CreateModel( + name="UserInvitation", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("code", models.CharField(max_length=64, unique=True)), + ( + "expires_at", + models.DateTimeField( + default=canopeum_backend.models.one_week_from_today + ), + ), + ("email", models.EmailField(max_length=254)), + ( + "assigned_to_sites", + models.ManyToManyField(to="canopeum_backend.site"), + ), + ], + ), + migrations.CreateModel( + name="Widget", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.TextField(blank=True, null=True)), + ("body", models.TextField(blank=True, null=True)), + ( + "site", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.site", + ), + ), + ], + ), + migrations.CreateModel( + name="Batchfertilizer", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "batch", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.batch", + ), + ), + ( + "fertilizer_type", + models.ForeignKey( + on_delete=django.db.models.deletion.RESTRICT, + to="canopeum_backend.fertilizertype", + ), + ), + ], + options={ + "constraints": [ + models.UniqueConstraint( + fields=("batch", "fertilizer_type"), + name="unique_fertilizer_per_batch", + ) + ], + }, + ), + migrations.CreateModel( + name="Batchmulchlayer", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "batch", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.batch", + ), + ), + ( + "mulch_layer_type", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.mulchlayertype", + ), + ), + ], + options={ + "constraints": [ + models.UniqueConstraint( + fields=("batch", "mulch_layer_type"), + name="unique_mulch_layer_per_batch", + ) + ], + }, + ), + migrations.CreateModel( + name="Sitetreespecies", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("quantity", models.IntegerField()), + ( + "site", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.site", + ), + ), + ( + "tree_type", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.treetype", + ), + ), + ], + options={ + "constraints": [ + models.UniqueConstraint( + fields=("site", "tree_type"), + name="unique_tree_species_per_site", + ) + ], + }, + ), + migrations.CreateModel( + name="BatchSupportedSpecies", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "batch", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.batch", + ), + ), + ( + "tree_type", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.treetype", + ), + ), + ], + options={ + "constraints": [ + models.UniqueConstraint( + fields=("batch", "tree_type"), + name="unique_supported_species_per_batch", + ) + ], + }, + ), + migrations.CreateModel( + name="BatchSpecies", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("quantity", models.IntegerField()), + ( + "batch", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.batch", + ), + ), + ( + "tree_type", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.treetype", + ), + ), + ], + options={ + "constraints": [ + models.UniqueConstraint( + fields=("batch", "tree_type"), name="unique_species_per_batch" + ) + ], + }, + ), + migrations.CreateModel( + name="BatchSeed", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("quantity", models.IntegerField()), + ( + "batch", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.batch", + ), + ), + ( + "tree_type", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.treetype", + ), + ), + ], + options={ + "constraints": [ + models.UniqueConstraint( + fields=("batch", "tree_type"), name="unique_seed_per_batch" + ) + ], + }, + ), + ] diff --git a/canopeum_backend/canopeum_backend/migrations/0002_alter_fertilizertype_name_alter_mulchlayertype_name_and_more.py b/canopeum_backend/canopeum_backend/migrations/0002_alter_fertilizertype_name_alter_mulchlayertype_name_and_more.py deleted file mode 100644 index 87736ed08..000000000 --- a/canopeum_backend/canopeum_backend/migrations/0002_alter_fertilizertype_name_alter_mulchlayertype_name_and_more.py +++ /dev/null @@ -1,62 +0,0 @@ -# Generated by Django 5.1 on 2024-10-03 18:38 - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ("canopeum_backend", "0001_initial"), - ] - - operations = [ - migrations.AlterField( - model_name="fertilizertype", - name="name", - field=models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.internationalization", - ), - ), - migrations.AlterField( - model_name="mulchlayertype", - name="name", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.internationalization", - ), - ), - migrations.AlterField( - model_name="sitetype", - name="name", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.internationalization", - ), - ), - migrations.AlterField( - model_name="treetype", - name="name", - field=models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.internationalization", - ), - ), - migrations.DeleteModel( - name="FertilizertypeInternationalization", - ), - migrations.DeleteModel( - name="MulchlayertypeInternationalization", - ), - migrations.DeleteModel( - name="SitetypeInternationalization", - ), - migrations.DeleteModel( - name="TreespeciestypeInternationalization", - ), - ] From 887584b6c468c1f871da95fdc90da799ebbcd23b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 22 Oct 2024 21:11:03 +0000 Subject: [PATCH 8/8] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .../migrations/0001_initial.py | 1874 ++++++++--------- 1 file changed, 937 insertions(+), 937 deletions(-) diff --git a/canopeum_backend/canopeum_backend/migrations/0001_initial.py b/canopeum_backend/canopeum_backend/migrations/0001_initial.py index 182a0d10b..3ac104a5a 100644 --- a/canopeum_backend/canopeum_backend/migrations/0001_initial.py +++ b/canopeum_backend/canopeum_backend/migrations/0001_initial.py @@ -1,937 +1,937 @@ -# Generated by Django 5.1 on 2024-10-22 21:07 - -import canopeum_backend.models -import django.contrib.auth.models -import django.contrib.auth.validators -import django.db.models.deletion -import django.utils.timezone -from django.conf import settings -from django.db import migrations, models - - -class Migration(migrations.Migration): - - initial = True - - dependencies = [ - ("auth", "0012_alter_user_first_name_max_length"), - ] - - operations = [ - migrations.CreateModel( - name="Announcement", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("body", models.TextField(blank=True, null=True)), - ("link", models.TextField(blank=True, null=True)), - ], - ), - migrations.CreateModel( - name="Asset", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "asset", - models.FileField(upload_to=canopeum_backend.models.upload_to), - ), - ], - ), - migrations.CreateModel( - name="Contact", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("address", models.TextField(blank=True, null=True)), - ("email", models.EmailField(blank=True, max_length=254, null=True)), - ("phone", models.CharField(blank=True, max_length=20, null=True)), - ("facebook_link", models.URLField(blank=True, null=True)), - ("x_link", models.URLField(blank=True, null=True)), - ("instagram_link", models.URLField(blank=True, null=True)), - ("linkedin_link", models.URLField(blank=True, null=True)), - ], - ), - migrations.CreateModel( - name="Coordinate", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("dms_latitude", models.TextField(blank=True, null=True)), - ("dms_longitude", models.TextField(blank=True, null=True)), - ( - "dd_latitude", - models.DecimalField( - blank=True, decimal_places=6, max_digits=9, null=True - ), - ), - ( - "dd_longitude", - models.DecimalField( - blank=True, decimal_places=6, max_digits=9, null=True - ), - ), - ("address", models.TextField(blank=True, null=True)), - ], - ), - migrations.CreateModel( - name="Internationalization", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("en", models.TextField(blank=True, db_column="EN", null=True)), - ("fr", models.TextField(blank=True, db_column="FR", null=True)), - ], - ), - migrations.CreateModel( - name="Post", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("body", models.TextField()), - ("share_count", models.IntegerField(default=0)), - ("created_at", models.DateTimeField(auto_now_add=True)), - ], - ), - migrations.CreateModel( - name="Role", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "name", - models.CharField( - choices=[ - ("User", "User"), - ("SiteManager", "Sitemanager"), - ("MegaAdmin", "Megaadmin"), - ], - default="User", - max_length=11, - ), - ), - ], - ), - migrations.CreateModel( - name="User", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("password", models.CharField(max_length=128, verbose_name="password")), - ( - "last_login", - models.DateTimeField( - blank=True, null=True, verbose_name="last login" - ), - ), - ( - "is_superuser", - models.BooleanField( - default=False, - help_text="Designates that this user has all permissions without explicitly assigning them.", - verbose_name="superuser status", - ), - ), - ( - "username", - models.CharField( - error_messages={ - "unique": "A user with that username already exists." - }, - help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.", - max_length=150, - unique=True, - validators=[ - django.contrib.auth.validators.UnicodeUsernameValidator() - ], - verbose_name="username", - ), - ), - ( - "first_name", - models.CharField( - blank=True, max_length=150, verbose_name="first name" - ), - ), - ( - "last_name", - models.CharField( - blank=True, max_length=150, verbose_name="last name" - ), - ), - ( - "is_staff", - models.BooleanField( - default=False, - help_text="Designates whether the user can log into this admin site.", - verbose_name="staff status", - ), - ), - ( - "is_active", - models.BooleanField( - default=True, - help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.", - verbose_name="active", - ), - ), - ( - "date_joined", - models.DateTimeField( - default=django.utils.timezone.now, verbose_name="date joined" - ), - ), - ( - "email", - models.EmailField( - max_length=255, unique=True, verbose_name="email address" - ), - ), - ( - "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", - ), - ), - ( - "role", - models.ForeignKey( - default=1, - on_delete=django.db.models.deletion.RESTRICT, - to="canopeum_backend.role", - ), - ), - ], - options={ - "verbose_name": "user", - "verbose_name_plural": "users", - "abstract": False, - }, - managers=[ - ("objects", django.contrib.auth.models.UserManager()), - ], - ), - migrations.CreateModel( - name="BatchSponsor", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("name", models.TextField()), - ("url", models.TextField()), - ( - "logo", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.asset", - ), - ), - ], - ), - migrations.CreateModel( - name="Fertilizertype", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "name", - models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.internationalization", - ), - ), - ], - ), - migrations.CreateModel( - name="Mulchlayertype", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "name", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.internationalization", - ), - ), - ], - ), - migrations.CreateModel( - name="Like", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "user", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to=settings.AUTH_USER_MODEL, - ), - ), - ( - "post", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.post", - ), - ), - ], - ), - migrations.CreateModel( - name="Comment", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("body", models.TextField()), - ("created_at", models.DateTimeField(auto_now_add=True)), - ( - "user", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to=settings.AUTH_USER_MODEL, - ), - ), - ( - "post", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.post", - ), - ), - ], - ), - migrations.CreateModel( - name="PostAsset", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "asset", - models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.asset", - ), - ), - ( - "post", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.post", - ), - ), - ], - ), - migrations.AddField( - model_name="post", - name="media", - field=models.ManyToManyField( - blank=True, - through="canopeum_backend.PostAsset", - to="canopeum_backend.asset", - ), - ), - migrations.CreateModel( - name="Site", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("name", models.TextField()), - ("is_public", models.BooleanField(default=False)), - ("description", models.TextField(blank=True, null=True)), - ("size", models.TextField(blank=True, null=True)), - ("research_partnership", models.BooleanField(blank=True, null=True)), - ("visible_map", models.BooleanField(blank=True, null=True)), - ("visitor_count", models.IntegerField(blank=True, null=True)), - ( - "announcement", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - to="canopeum_backend.announcement", - ), - ), - ( - "contact", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - to="canopeum_backend.contact", - ), - ), - ( - "coordinate", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - to="canopeum_backend.coordinate", - ), - ), - ( - "image", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - to="canopeum_backend.asset", - ), - ), - ], - ), - migrations.AddField( - model_name="post", - name="site", - field=models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, to="canopeum_backend.site" - ), - ), - migrations.CreateModel( - name="Batch", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("created_at", models.DateTimeField(auto_now_add=True, null=True)), - ("updated_at", models.DateTimeField(auto_now=True, null=True)), - ("name", models.TextField(blank=True, null=True)), - ("size", models.IntegerField(blank=True, null=True)), - ("soil_condition", models.TextField(blank=True, null=True)), - ("survived_count", models.IntegerField(blank=True, null=True)), - ("replace_count", models.IntegerField(blank=True, null=True)), - ("total_number_seed", models.IntegerField(blank=True, null=True)), - ("total_propagation", models.IntegerField(blank=True, null=True)), - ( - "image", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.asset", - ), - ), - ( - "sponsor", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.batchsponsor", - ), - ), - ( - "site", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.site", - ), - ), - ], - ), - migrations.CreateModel( - name="Siteadmin", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "site", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.site", - ), - ), - ( - "user", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to=settings.AUTH_USER_MODEL, - ), - ), - ], - ), - migrations.CreateModel( - name="SiteFollower", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("created_at", models.DateTimeField(auto_now_add=True)), - ( - "site", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.site", - ), - ), - ( - "user", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to=settings.AUTH_USER_MODEL, - ), - ), - ], - ), - migrations.CreateModel( - name="Sitetype", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "name", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.internationalization", - ), - ), - ], - ), - migrations.AddField( - model_name="site", - name="site_type", - field=models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.sitetype", - ), - ), - migrations.CreateModel( - name="Treetype", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "name", - models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.internationalization", - ), - ), - ], - ), - migrations.CreateModel( - name="UserInvitation", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("code", models.CharField(max_length=64, unique=True)), - ( - "expires_at", - models.DateTimeField( - default=canopeum_backend.models.one_week_from_today - ), - ), - ("email", models.EmailField(max_length=254)), - ( - "assigned_to_sites", - models.ManyToManyField(to="canopeum_backend.site"), - ), - ], - ), - migrations.CreateModel( - name="Widget", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("title", models.TextField(blank=True, null=True)), - ("body", models.TextField(blank=True, null=True)), - ( - "site", - models.ForeignKey( - blank=True, - null=True, - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.site", - ), - ), - ], - ), - migrations.CreateModel( - name="Batchfertilizer", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "batch", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.batch", - ), - ), - ( - "fertilizer_type", - models.ForeignKey( - on_delete=django.db.models.deletion.RESTRICT, - to="canopeum_backend.fertilizertype", - ), - ), - ], - options={ - "constraints": [ - models.UniqueConstraint( - fields=("batch", "fertilizer_type"), - name="unique_fertilizer_per_batch", - ) - ], - }, - ), - migrations.CreateModel( - name="Batchmulchlayer", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "batch", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.batch", - ), - ), - ( - "mulch_layer_type", - models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.mulchlayertype", - ), - ), - ], - options={ - "constraints": [ - models.UniqueConstraint( - fields=("batch", "mulch_layer_type"), - name="unique_mulch_layer_per_batch", - ) - ], - }, - ), - migrations.CreateModel( - name="Sitetreespecies", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("quantity", models.IntegerField()), - ( - "site", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.site", - ), - ), - ( - "tree_type", - models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.treetype", - ), - ), - ], - options={ - "constraints": [ - models.UniqueConstraint( - fields=("site", "tree_type"), - name="unique_tree_species_per_site", - ) - ], - }, - ), - migrations.CreateModel( - name="BatchSupportedSpecies", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ( - "batch", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.batch", - ), - ), - ( - "tree_type", - models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.treetype", - ), - ), - ], - options={ - "constraints": [ - models.UniqueConstraint( - fields=("batch", "tree_type"), - name="unique_supported_species_per_batch", - ) - ], - }, - ), - migrations.CreateModel( - name="BatchSpecies", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("quantity", models.IntegerField()), - ( - "batch", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.batch", - ), - ), - ( - "tree_type", - models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.treetype", - ), - ), - ], - options={ - "constraints": [ - models.UniqueConstraint( - fields=("batch", "tree_type"), name="unique_species_per_batch" - ) - ], - }, - ), - migrations.CreateModel( - name="BatchSeed", - fields=[ - ( - "id", - models.BigAutoField( - auto_created=True, - primary_key=True, - serialize=False, - verbose_name="ID", - ), - ), - ("quantity", models.IntegerField()), - ( - "batch", - models.ForeignKey( - on_delete=django.db.models.deletion.CASCADE, - to="canopeum_backend.batch", - ), - ), - ( - "tree_type", - models.ForeignKey( - on_delete=django.db.models.deletion.DO_NOTHING, - to="canopeum_backend.treetype", - ), - ), - ], - options={ - "constraints": [ - models.UniqueConstraint( - fields=("batch", "tree_type"), name="unique_seed_per_batch" - ) - ], - }, - ), - ] +# Generated by Django 5.1 on 2024-10-22 21:07 + +import canopeum_backend.models +import django.contrib.auth.models +import django.contrib.auth.validators +import django.db.models.deletion +import django.utils.timezone +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ("auth", "0012_alter_user_first_name_max_length"), + ] + + operations = [ + migrations.CreateModel( + name="Announcement", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("body", models.TextField(blank=True, null=True)), + ("link", models.TextField(blank=True, null=True)), + ], + ), + migrations.CreateModel( + name="Asset", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "asset", + models.FileField(upload_to=canopeum_backend.models.upload_to), + ), + ], + ), + migrations.CreateModel( + name="Contact", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("address", models.TextField(blank=True, null=True)), + ("email", models.EmailField(blank=True, max_length=254, null=True)), + ("phone", models.CharField(blank=True, max_length=20, null=True)), + ("facebook_link", models.URLField(blank=True, null=True)), + ("x_link", models.URLField(blank=True, null=True)), + ("instagram_link", models.URLField(blank=True, null=True)), + ("linkedin_link", models.URLField(blank=True, null=True)), + ], + ), + migrations.CreateModel( + name="Coordinate", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("dms_latitude", models.TextField(blank=True, null=True)), + ("dms_longitude", models.TextField(blank=True, null=True)), + ( + "dd_latitude", + models.DecimalField( + blank=True, decimal_places=6, max_digits=9, null=True + ), + ), + ( + "dd_longitude", + models.DecimalField( + blank=True, decimal_places=6, max_digits=9, null=True + ), + ), + ("address", models.TextField(blank=True, null=True)), + ], + ), + migrations.CreateModel( + name="Internationalization", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("en", models.TextField(blank=True, db_column="EN", null=True)), + ("fr", models.TextField(blank=True, db_column="FR", null=True)), + ], + ), + migrations.CreateModel( + name="Post", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("body", models.TextField()), + ("share_count", models.IntegerField(default=0)), + ("created_at", models.DateTimeField(auto_now_add=True)), + ], + ), + migrations.CreateModel( + name="Role", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "name", + models.CharField( + choices=[ + ("User", "User"), + ("SiteManager", "Sitemanager"), + ("MegaAdmin", "Megaadmin"), + ], + default="User", + max_length=11, + ), + ), + ], + ), + migrations.CreateModel( + name="User", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("password", models.CharField(max_length=128, verbose_name="password")), + ( + "last_login", + models.DateTimeField( + blank=True, null=True, verbose_name="last login" + ), + ), + ( + "is_superuser", + models.BooleanField( + default=False, + help_text="Designates that this user has all permissions without explicitly assigning them.", + verbose_name="superuser status", + ), + ), + ( + "username", + models.CharField( + error_messages={ + "unique": "A user with that username already exists." + }, + help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.", + max_length=150, + unique=True, + validators=[ + django.contrib.auth.validators.UnicodeUsernameValidator() + ], + verbose_name="username", + ), + ), + ( + "first_name", + models.CharField( + blank=True, max_length=150, verbose_name="first name" + ), + ), + ( + "last_name", + models.CharField( + blank=True, max_length=150, verbose_name="last name" + ), + ), + ( + "is_staff", + models.BooleanField( + default=False, + help_text="Designates whether the user can log into this admin site.", + verbose_name="staff status", + ), + ), + ( + "is_active", + models.BooleanField( + default=True, + help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.", + verbose_name="active", + ), + ), + ( + "date_joined", + models.DateTimeField( + default=django.utils.timezone.now, verbose_name="date joined" + ), + ), + ( + "email", + models.EmailField( + max_length=255, unique=True, verbose_name="email address" + ), + ), + ( + "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", + ), + ), + ( + "role", + models.ForeignKey( + default=1, + on_delete=django.db.models.deletion.RESTRICT, + to="canopeum_backend.role", + ), + ), + ], + options={ + "verbose_name": "user", + "verbose_name_plural": "users", + "abstract": False, + }, + managers=[ + ("objects", django.contrib.auth.models.UserManager()), + ], + ), + migrations.CreateModel( + name="BatchSponsor", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.TextField()), + ("url", models.TextField()), + ( + "logo", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.asset", + ), + ), + ], + ), + migrations.CreateModel( + name="Fertilizertype", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "name", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + ], + ), + migrations.CreateModel( + name="Mulchlayertype", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "name", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + ], + ), + migrations.CreateModel( + name="Like", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "post", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.post", + ), + ), + ], + ), + migrations.CreateModel( + name="Comment", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("body", models.TextField()), + ("created_at", models.DateTimeField(auto_now_add=True)), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ( + "post", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.post", + ), + ), + ], + ), + migrations.CreateModel( + name="PostAsset", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "asset", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.asset", + ), + ), + ( + "post", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.post", + ), + ), + ], + ), + migrations.AddField( + model_name="post", + name="media", + field=models.ManyToManyField( + blank=True, + through="canopeum_backend.PostAsset", + to="canopeum_backend.asset", + ), + ), + migrations.CreateModel( + name="Site", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.TextField()), + ("is_public", models.BooleanField(default=False)), + ("description", models.TextField(blank=True, null=True)), + ("size", models.TextField(blank=True, null=True)), + ("research_partnership", models.BooleanField(blank=True, null=True)), + ("visible_map", models.BooleanField(blank=True, null=True)), + ("visitor_count", models.IntegerField(blank=True, null=True)), + ( + "announcement", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="canopeum_backend.announcement", + ), + ), + ( + "contact", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="canopeum_backend.contact", + ), + ), + ( + "coordinate", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="canopeum_backend.coordinate", + ), + ), + ( + "image", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="canopeum_backend.asset", + ), + ), + ], + ), + migrations.AddField( + model_name="post", + name="site", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="canopeum_backend.site" + ), + ), + migrations.CreateModel( + name="Batch", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True, null=True)), + ("updated_at", models.DateTimeField(auto_now=True, null=True)), + ("name", models.TextField(blank=True, null=True)), + ("size", models.IntegerField(blank=True, null=True)), + ("soil_condition", models.TextField(blank=True, null=True)), + ("survived_count", models.IntegerField(blank=True, null=True)), + ("replace_count", models.IntegerField(blank=True, null=True)), + ("total_number_seed", models.IntegerField(blank=True, null=True)), + ("total_propagation", models.IntegerField(blank=True, null=True)), + ( + "image", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.asset", + ), + ), + ( + "sponsor", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.batchsponsor", + ), + ), + ( + "site", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.site", + ), + ), + ], + ), + migrations.CreateModel( + name="Siteadmin", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "site", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.site", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.CreateModel( + name="SiteFollower", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("created_at", models.DateTimeField(auto_now_add=True)), + ( + "site", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.site", + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + migrations.CreateModel( + name="Sitetype", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "name", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + ], + ), + migrations.AddField( + model_name="site", + name="site_type", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.sitetype", + ), + ), + migrations.CreateModel( + name="Treetype", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "name", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.internationalization", + ), + ), + ], + ), + migrations.CreateModel( + name="UserInvitation", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("code", models.CharField(max_length=64, unique=True)), + ( + "expires_at", + models.DateTimeField( + default=canopeum_backend.models.one_week_from_today + ), + ), + ("email", models.EmailField(max_length=254)), + ( + "assigned_to_sites", + models.ManyToManyField(to="canopeum_backend.site"), + ), + ], + ), + migrations.CreateModel( + name="Widget", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.TextField(blank=True, null=True)), + ("body", models.TextField(blank=True, null=True)), + ( + "site", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.site", + ), + ), + ], + ), + migrations.CreateModel( + name="Batchfertilizer", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "batch", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.batch", + ), + ), + ( + "fertilizer_type", + models.ForeignKey( + on_delete=django.db.models.deletion.RESTRICT, + to="canopeum_backend.fertilizertype", + ), + ), + ], + options={ + "constraints": [ + models.UniqueConstraint( + fields=("batch", "fertilizer_type"), + name="unique_fertilizer_per_batch", + ) + ], + }, + ), + migrations.CreateModel( + name="Batchmulchlayer", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "batch", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.batch", + ), + ), + ( + "mulch_layer_type", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.mulchlayertype", + ), + ), + ], + options={ + "constraints": [ + models.UniqueConstraint( + fields=("batch", "mulch_layer_type"), + name="unique_mulch_layer_per_batch", + ) + ], + }, + ), + migrations.CreateModel( + name="Sitetreespecies", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("quantity", models.IntegerField()), + ( + "site", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.site", + ), + ), + ( + "tree_type", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.treetype", + ), + ), + ], + options={ + "constraints": [ + models.UniqueConstraint( + fields=("site", "tree_type"), + name="unique_tree_species_per_site", + ) + ], + }, + ), + migrations.CreateModel( + name="BatchSupportedSpecies", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "batch", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.batch", + ), + ), + ( + "tree_type", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.treetype", + ), + ), + ], + options={ + "constraints": [ + models.UniqueConstraint( + fields=("batch", "tree_type"), + name="unique_supported_species_per_batch", + ) + ], + }, + ), + migrations.CreateModel( + name="BatchSpecies", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("quantity", models.IntegerField()), + ( + "batch", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.batch", + ), + ), + ( + "tree_type", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.treetype", + ), + ), + ], + options={ + "constraints": [ + models.UniqueConstraint( + fields=("batch", "tree_type"), name="unique_species_per_batch" + ) + ], + }, + ), + migrations.CreateModel( + name="BatchSeed", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("quantity", models.IntegerField()), + ( + "batch", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="canopeum_backend.batch", + ), + ), + ( + "tree_type", + models.ForeignKey( + on_delete=django.db.models.deletion.DO_NOTHING, + to="canopeum_backend.treetype", + ), + ), + ], + options={ + "constraints": [ + models.UniqueConstraint( + fields=("batch", "tree_type"), name="unique_seed_per_batch" + ) + ], + }, + ), + ]