From a4935700b1e882f20d00cea6043965787b991f19 Mon Sep 17 00:00:00 2001 From: George Katsikas <giorgakis.katsikas@gmail.com> Date: Fri, 15 Mar 2024 16:39:22 +0100 Subject: [PATCH] add notes and pins models related to #164 --- scipost_django/pins/admin.py | 25 ++++- .../pins/migrations/0001_initial.py | 103 ++++++++++++++++++ scipost_django/pins/models.py | 61 ++++++++++- 3 files changed, 187 insertions(+), 2 deletions(-) create mode 100644 scipost_django/pins/migrations/0001_initial.py diff --git a/scipost_django/pins/admin.py b/scipost_django/pins/admin.py index 6a7921658..7b6608d52 100644 --- a/scipost_django/pins/admin.py +++ b/scipost_django/pins/admin.py @@ -3,4 +3,27 @@ __license__ = "AGPL v3" from django.contrib import admin -# Register your models here. +from pins.models import Note + + +@admin.register(Note) +class NoteAdmin(admin.ModelAdmin): + list_display = ("id", "regarding__object", "title", "author", "created", "modified") + list_filter = ("created", "modified", "visibility", "regarding_content_type") + search_fields = ("title", "author__username") + date_hierarchy = "created" + ordering = ("-created",) + readonly_fields = ("created", "modified", "regarding") + fields = ( + "title", + "description", + "regarding", + "visibility", + "author", + "created", + "modified", + ) + autocomplete_fields = ("author",) + + def regarding__object(self, obj): + return str(obj.regarding) diff --git a/scipost_django/pins/migrations/0001_initial.py b/scipost_django/pins/migrations/0001_initial.py new file mode 100644 index 000000000..bbfa7c661 --- /dev/null +++ b/scipost_django/pins/migrations/0001_initial.py @@ -0,0 +1,103 @@ +# Generated by Django 4.2.10 on 2024-03-15 15:53 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + initial = True + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ( + "scipost", + "0041_alter_remark_contributor_alter_remark_recommendation_and_more", + ), + ("contenttypes", "0002_remove_content_type_name"), + ] + + operations = [ + migrations.CreateModel( + name="Note", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("title", models.CharField(max_length=255)), + ("description", models.TextField()), + ( + "visibility", + models.CharField( + choices=[ + ("self", "Private"), + ("internal", "Internal"), + ("public", "Public"), + ], + default="self", + max_length=10, + ), + ), + ( + "regarding_object_id", + models.PositiveIntegerField(blank=True, null=True), + ), + ("created", models.DateTimeField(auto_now_add=True)), + ("modified", models.DateTimeField(auto_now=True)), + ( + "author", + models.ForeignKey( + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="scipost.contributor", + ), + ), + ( + "regarding_content_type", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="contenttypes.contenttype", + ), + ), + ], + options={ + "ordering": ("-created",), + "default_related_name": "notes", + }, + ), + migrations.CreateModel( + name="Pin", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("due_date", models.DateField(blank=True, null=True)), + ("created", models.DateTimeField(auto_now_add=True)), + ( + "note", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="pins.note" + ), + ), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + ] diff --git a/scipost_django/pins/models.py b/scipost_django/pins/models.py index dbbe360b1..88a7ff9ed 100644 --- a/scipost_django/pins/models.py +++ b/scipost_django/pins/models.py @@ -2,5 +2,64 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" __license__ = "AGPL v3" from django.db import models +from django.contrib.contenttypes.fields import GenericForeignKey -# Create your models here. + +class Note(models.Model): + """ + A note regarding a (generic) object. + """ + + class Meta: + ordering = ("-created",) + default_related_name = "notes" + + VISIBILITY_PRIVATE = "self" + VISIBILITY_INTERNAL = "internal" + VISIBILITY_PUBLIC = "public" # Notes for everyone + VISIBILITY_CHOICES = ( + (VISIBILITY_PRIVATE, "Private"), # For creator only + (VISIBILITY_INTERNAL, "Internal"), # For group of object managers + (VISIBILITY_PUBLIC, "Public"), # For everyone + ) + + title = models.CharField(max_length=255) + description = models.TextField() + visibility = models.CharField( + max_length=10, + default=VISIBILITY_PRIVATE, + choices=VISIBILITY_CHOICES, + ) + + regarding_content_type = models.ForeignKey( + "contenttypes.ContentType", + on_delete=models.CASCADE, + ) + regarding_object_id = models.PositiveIntegerField(blank=True, null=True) + regarding = GenericForeignKey("regarding_content_type", "regarding_object_id") + + author = models.ForeignKey( + "scipost.Contributor", + on_delete=models.CASCADE, + null=True, + ) + created = models.DateTimeField(auto_now_add=True) + modified = models.DateTimeField(auto_now=True) + + def __str__(self): + return self.title + + +class Pin(models.Model): + """ + A pin associates a note with a user, making it visible in their task list. + """ + + note = models.ForeignKey(Note, on_delete=models.CASCADE) + user = models.ForeignKey("auth.User", on_delete=models.CASCADE) + due_date = models.DateField(blank=True, null=True) + + created = models.DateTimeField(auto_now_add=True) + + def __str__(self): + return f"Pin of {self.note} for {self.user}" -- GitLab