diff --git a/app/migrations/0014_notification_followers.py b/app/migrations/0014_notification_followers.py new file mode 100644 index 0000000..8d5b35b --- /dev/null +++ b/app/migrations/0014_notification_followers.py @@ -0,0 +1,44 @@ +# Generated by Django 3.0.10 on 2020-09-19 22:58 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('contenttypes', '0002_remove_content_type_name'), + ('app', '0013_auto_20200919_0144'), + ] + + operations = [ + migrations.CreateModel( + name='Notification', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('message', models.CharField(help_text='Notification message.', max_length=255, verbose_name='Message')), + ('object_id', models.PositiveIntegerField(null=True, verbose_name='Linked Item ID')), + ('created', models.DateTimeField(auto_now_add=True, help_text='Date this notification was sent.', verbose_name='Creation Date')), + ('content_type', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType', verbose_name='Linked Item Type')), + ], + ), + migrations.AddField( + model_name='challenge', + name='followers', + field=models.ManyToManyField(help_text='Followers of this project who will receive notifications about it.', related_name='followed_challenges', to='app.Profile', verbose_name='Followers'), + ), + migrations.AddField( + model_name='project', + name='followers', + field=models.ManyToManyField(help_text='Followers of this project who will receive notifications about it.', related_name='followed_projects', to='app.Profile', verbose_name='Followers'), + ), + migrations.CreateModel( + name='NotificationInstance', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('is_read', models.BooleanField(default=False, help_text='Whether this notification has been read.', verbose_name='Is Read')), + ('notification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notifications', to='app.Notification')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notifications', to='app.Profile')), + ], + ), + ] diff --git a/app/models.py b/app/models.py index df43de6..232761e 100644 --- a/app/models.py +++ b/app/models.py @@ -137,6 +137,12 @@ class Challenge(models.Model): help_text="Creators of this challenge which can edit its properties. Removing yourself " + "will make it impossible to edit this challenge.", ) + followers = models.ManyToManyField( + Profile, + related_name="followed_challenges", + verbose_name="Followers", + help_text="Followers of this project who will receive notifications about it.", + ) created = models.DateField( auto_now_add=True, verbose_name="Creation Date", @@ -235,6 +241,12 @@ class Project(models.Model): help_text="Creators of this project which can edit its properties. Removing yourself will " + "make it impossible for you to edit this project.", ) + followers = models.ManyToManyField( + Profile, + related_name="followed_projects", + verbose_name="Followers", + help_text="Followers of this project who will receive notifications about it.", + ) created = models.DateField( auto_now_add=True, verbose_name="Creation Date", help_text="Date this project was created." ) @@ -270,3 +282,34 @@ def __str__(self): def create_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) + + +class Notification(models.Model): + message = models.CharField( + max_length=255, verbose_name="Message", help_text="Notification message." + ) + content_type = models.ForeignKey( + ContentType, null=True, verbose_name="Linked Item Type", on_delete=models.CASCADE + ) + object_id = models.PositiveIntegerField(null=True, verbose_name="Linked Item ID") + linked_item = GenericForeignKey() + created = models.DateTimeField( + auto_now_add=True, + verbose_name="Creation Date", + help_text="Date this notification was sent.", + ) + + def get_link_url(self): + if self.linked_item: + return self.linked_item.get_absolute_url() + return "#" + + +class NotificationInstance(models.Model): + notification = models.ForeignKey( + Notification, related_name="notifications", on_delete=models.CASCADE + ) + user = models.ForeignKey(Profile, related_name="notifications", on_delete=models.CASCADE) + is_read = models.BooleanField( + default=False, verbose_name="Is Read", help_text="Whether this notification has been read." + )