]> git.menne-pb.de Git - pinpoint.git/commitdiff
Model rewrite for category and report finished
authorJörn Menne <jmenne@fedora.de>
Wed, 5 Feb 2025 10:29:42 +0000 (11:29 +0100)
committerJörn Menne <jmenne@fedora.de>
Wed, 5 Feb 2025 10:29:42 +0000 (11:29 +0100)
Currently the loction is not included into the report, since it will
become an own model.

.gitignore
doc-requirements.txt [new file with mode: 0644]
doc/conf.py
doc/georeport/models.rst
doc/index.rst
georeport/__init__.py
georeport/migrations/0001_initial.py [new file with mode: 0644]
georeport/models.py
georeport/tests.py

index 1c92262b8bf659453c47ca704421feaa099212cd..24ae4f164722c47ec90147c9af030496033c5b91 100644 (file)
@@ -1,3 +1,7 @@
 __pycache__/
 
 db.sqlite3
+
+
+doc/_build
+doc/build
diff --git a/doc-requirements.txt b/doc-requirements.txt
new file mode 100644 (file)
index 0000000..ca4d1ea
--- /dev/null
@@ -0,0 +1,3 @@
+sphinx 
+sphinxcontrib-plantuml
+-r requirements.txt
index 90560805c9661608fb502838b8b09cdff7a93300..743f6172cc1dea7a670d1e477a08e8cc9ef9f062 100644 (file)
@@ -16,7 +16,7 @@ django.setup()
 project = "Pinpoint-Report"
 copyright = "2025, Jörn Menne"
 author = "Jörn Menne"
-release = "0.1"
+release = "0.1.5"
 
 # -- General configuration ---------------------------------------------------
 # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
@@ -27,6 +27,8 @@ extensions = [
     "sphinx.ext.napoleon",
     "sphinxcontrib.plantuml",
     "sphinx.ext.mathjax",
+    "myst_parser",
+    "sphinx.ext.todo",
 ]
 
 templates_path = ["_templates"]
@@ -38,3 +40,7 @@ exclude_patterns = []
 
 html_theme = "alabaster"
 html_static_path = ["_static"]
+
+
+# Options for todo
+todo_include_todos = True
index 3d7d4479a312a999110215946ad2b0fde904ffdd..f2331850d2a174fa59da0c5a9f47ca0ce4422da4 100644 (file)
@@ -1,6 +1,32 @@
 Models
 ======
 
-Here are the models used in Pinpoint-Report
+.. todo::
 
+    Split into 2 files. 1 to read and one for the autodoc
+
+The models represent the structure in the datebase as such, that each model 
+is a table in the database. 
+The translation from the *models.py* file to the specifc tables is done by
+django with the help of migrations.
+
+After each alteration of a model-class the following two scripts have to be run.
+.. code:: 
+    
+    python manage migrations
+    python manage migrate 
+
+The first command creates a migration file, while the second one applies the migration to the database.
+
+The following models are used: 
+
+* Category
+* Report 
+
+Categories are used to group reports and assing the corresponding staff. This is done by preventing access to users,
+which have not authority about the category
+
+.. automodule:: georeport.models
+   :members:
+   :undoc-members:
 
index 92425bbd3fc11602269f923d92742dcec5e00db5..ed6580e047642a8c75280aec17f117a82e9950b4 100644 (file)
@@ -16,3 +16,6 @@ documentation for details.
     :caption: Contents:
 
     georeport/models
+    
+
+.. todolist::
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e6b3e86e5296a950b629097c2adae1cbff08bdb6 100644 (file)
@@ -0,0 +1 @@
+version="0.1.5"
diff --git a/georeport/migrations/0001_initial.py b/georeport/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..4bbdcae
--- /dev/null
@@ -0,0 +1,109 @@
+# Generated by Django 5.1.5 on 2025-02-05 10:09
+
+import django.db.models.deletion
+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"),
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="Category",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("name", models.CharField(max_length=100)),
+                (
+                    "groups",
+                    models.ManyToManyField(
+                        blank=True, related_name="group_owner", to="auth.group"
+                    ),
+                ),
+                (
+                    "parent",
+                    models.ForeignKey(
+                        blank=True,
+                        null=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="subcategories",
+                        to="georeport.category",
+                    ),
+                ),
+                (
+                    "user",
+                    models.ManyToManyField(
+                        blank=True, related_name="owner", to=settings.AUTH_USER_MODEL
+                    ),
+                ),
+            ],
+            options={
+                "verbose_name_plural": "Categories",
+            },
+        ),
+        migrations.CreateModel(
+            name="Report",
+            fields=[
+                (
+                    "id",
+                    models.BigAutoField(
+                        auto_created=True,
+                        primary_key=True,
+                        serialize=False,
+                        verbose_name="ID",
+                    ),
+                ),
+                ("created_at", models.DateTimeField(auto_now=True)),
+                ("updated_at", models.DateTimeField(auto_now_add=True)),
+                ("title", models.CharField(max_length=100, unique=True)),
+                ("descrption", models.TextField(blank=True, null=True)),
+                ("email", models.EmailField(max_length=254)),
+                (
+                    "state",
+                    models.IntegerField(
+                        choices=[
+                            (0, "New"),
+                            (1, "In Progess"),
+                            (2, "Finished"),
+                            (3, "Archive"),
+                        ],
+                        default=0,
+                    ),
+                ),
+                (
+                    "_oldState",
+                    models.IntegerField(
+                        choices=[
+                            (0, "New"),
+                            (1, "In Progess"),
+                            (2, "Finished"),
+                            (3, "Archive"),
+                        ],
+                        default=0,
+                    ),
+                ),
+                ("published", models.BooleanField(default=False)),
+                (
+                    "category",
+                    models.ForeignKey(
+                        on_delete=django.db.models.deletion.RESTRICT,
+                        related_name="reports",
+                        to="georeport.category",
+                    ),
+                ),
+            ],
+        ),
+    ]
index 71a836239075aa6e6e4ecb700e9c42c95c022d91..123f484ba2655e59ab99e9453f09d10bfdbe85f4 100644 (file)
@@ -1,3 +1,85 @@
+# Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
+# GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
+"""
+Module which contains classes representing the database structure
+of the project.
+"""
+
 from django.db import models
+from django.contrib.auth.models import Group, User
+from typing import override
 
 # Create your models here.
+
+
+class Category(models.Model):
+    """
+    A class representing a Category in the database.
+    """
+
+    # TODO: Prevent circles
+    name = models.CharField(max_length=100)
+    parent = models.ForeignKey(
+        "self",
+        on_delete=models.CASCADE,
+        related_name="subcategories",
+        null=True,
+        blank=True,
+    )
+
+    user = models.ManyToManyField(User, related_name="owner", blank=True)
+    groups = models.ManyToManyField(Group, related_name="group_owner", blank=True)
+
+    class Meta:
+        verbose_name_plural = "Categories"
+
+    @override
+    def __str__(self) -> str:
+        return str(self.name)
+
+
+class Report(models.Model):
+    """
+    A class representing a Report in the database.
+    """
+
+    class State(models.IntegerChoices):
+        """
+        A small class, which provide the possible states of a report
+        """
+
+        NEW = 0
+        IN_PROGESS = 1
+        FINISHED = 2
+        ARCHIVE = 3
+
+    # Timebased autofields
+    created_at = models.DateTimeField(auto_now=True)
+    updated_at = models.DateTimeField(auto_now_add=True)
+
+    # Fields to be filled at creation time
+    category = models.ForeignKey(
+        Category, on_delete=models.RESTRICT, related_name="reports"
+    )
+    title = models.CharField(max_length=100, unique=True)
+    descrption = models.TextField(blank=True, null=True)
+    email = models.EmailField()
+    # TODO: Images
+
+    # Fields set at creation
+    state = models.IntegerField(choices=State, default=0)  # type: ignore Correct type can not be dtermined
+    _oldState = models.IntegerField(choices=State, default=0)  # type: ignore Correct type can not be dtermined
+
+    """
+        The old statevariable is neede to determine, if the state was changed.
+    """
+    published = models.BooleanField(default=False)  # type: ignore Correct type can not be dtermined
+
+    @override
+    def __str__(self) -> str:
+        return str(self.title)
+
+
+# TODO: Location
+
+# TODO: Image
index 7ce503c2dd97ba78597f6ff6e4393132753573f6..94d3c8f4bdb64d36c6f9d3d4c0d91d403b232cb4 100644 (file)
@@ -1,3 +1,20 @@
+# Copyright: (c) 2025, Jörn Menne <jmenne@posteo.de>
+# GNU General Public License v3.0 (see LICSENE or https://www.gnu.org/license/gpl-3.0.md)
+
 from django.test import TestCase
 
-# Create your tests here.
+from .models import Category, Report
+
+
+class ReportTestCase(TestCase):
+    def setUp(self):
+        Category.objects.create(name="Cat1")  # type:ignore Attribute object is unknown
+        Report.objects.create(  # type:ignore Attribute object is unknown
+            title="Test",
+            email="test@test.de",
+            category=Category.objects.first(),  # type:ignore Attribute object is unknown
+        )
+
+    def test_unpulished_as_default(self):
+        report = Report.objects.get(title="Test")  # type:ignore Attribute object is unknown
+        self.assertEqual(report.published, False)