Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@
admin.site.register(models.Task)
admin.site.register(models.Access)
admin.site.register(models.Label)
admin.site.register(models.Notification)
37 changes: 37 additions & 0 deletions api/migrations/0004_notification.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2017-03-23 00:41
from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('api', '0003_task_done'),
]

operations = [
migrations.CreateModel(
name='Notification',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('published_date', models.DateField(verbose_name='Published date')),
('modification_date', models.DateField(blank=True, null=True, verbose_name='Modification Date')),
('status', models.IntegerField(default=1, verbose_name='Status')),
('target_type', models.CharField(max_length=50, verbose_name='Target type')),
('target_id', models.PositiveIntegerField(verbose_name='Target ID')),
('target_intention', models.CharField(max_length=50, verbose_name='Target intention')),
('title', models.CharField(max_length=255, verbose_name='Title')),
('text', models.TextField(verbose_name='Text')),
('receiver', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notifications_received', to=settings.AUTH_USER_MODEL, verbose_name='Receiver')),
('sender', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notification_sent', to=settings.AUTH_USER_MODEL, verbose_name='Sender')),
],
options={
'verbose_name_plural': 'Notifications',
},
),
]
20 changes: 20 additions & 0 deletions api/migrations/0005_notification_is_read.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2017-03-23 01:34
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('api', '0004_notification'),
]

operations = [
migrations.AddField(
model_name='notification',
name='is_read',
field=models.BooleanField(default=0, verbose_name='Is read'),
),
]
24 changes: 24 additions & 0 deletions api/migrations/0006_task_created_by.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2017-03-23 03:03
from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('api', '0005_notification_is_read'),
]

operations = [
migrations.AddField(
model_name='task',
name='created_by',
field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.CASCADE, related_name='task_created', to=settings.AUTH_USER_MODEL, verbose_name='Created by'),
preserve_default=False,
),
]
22 changes: 22 additions & 0 deletions api/migrations/0007_auto_20170323_0350.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2017-03-23 03:50
from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('api', '0006_task_created_by'),
]

operations = [
migrations.AlterField(
model_name='task',
name='created_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='task_created', to=settings.AUTH_USER_MODEL, verbose_name='Created by'),
),
]
23 changes: 23 additions & 0 deletions api/migrations/0008_auto_20170323_0351.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2017-03-23 03:51
from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('api', '0007_auto_20170323_0350'),
]

operations = [
migrations.AlterField(
model_name='task',
name='created_by',
field=models.ForeignKey(blank=True, default=1, on_delete=django.db.models.deletion.CASCADE, related_name='task_created', to=settings.AUTH_USER_MODEL, verbose_name='Created by'),
preserve_default=False,
),
]
22 changes: 22 additions & 0 deletions api/migrations/0009_auto_20170323_0352.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2017-03-23 03:52
from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('api', '0008_auto_20170323_0351'),
]

operations = [
migrations.AlterField(
model_name='task',
name='created_by',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='task_created', to=settings.AUTH_USER_MODEL, verbose_name='Created by'),
),
]
23 changes: 23 additions & 0 deletions api/migrations/0010_auto_20170323_0353.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10 on 2017-03-23 03:53
from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('api', '0009_auto_20170323_0352'),
]

operations = [
migrations.AlterField(
model_name='task',
name='created_by',
field=models.ForeignKey(blank=True, default=1, on_delete=django.db.models.deletion.CASCADE, related_name='task_created', to=settings.AUTH_USER_MODEL, verbose_name='Created by'),
preserve_default=False,
),
]
87 changes: 87 additions & 0 deletions api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from django.db import models

from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver


RIGHT_ACCESS = (
Expand Down Expand Up @@ -107,6 +109,13 @@ class Meta:
related_name="tasks"
)

created_by = models.ForeignKey(
User,
verbose_name='Created by',
related_name='task_created',
blank=True
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure with this line. I think it may be good to have this field required.

)

assigned = models.ForeignKey(
User,
verbose_name='assigned',
Expand Down Expand Up @@ -255,3 +264,81 @@ class Meta:

def __unicode__(self):
return self.name


class Notification(models.Model):
class Meta:
verbose_name_plural = "Notifications"

sender = models.ForeignKey(
User,
verbose_name='Sender',
related_name='notification_sent'
)

receiver = models.ForeignKey(
User,
verbose_name='Receiver',
related_name='notifications_received'
)

published_date = models.DateField(
verbose_name='Published date'
)

modification_date = models.DateField(
verbose_name='Modification Date',
blank=True,
null=True
)

status = models.IntegerField(
verbose_name='Status',
default=1
)

is_read = models.BooleanField(
verbose_name='Is read',
default=0
)

target_type = models.CharField(
verbose_name='Target type',
max_length=50
)

target_id = models.PositiveIntegerField(
verbose_name='Target ID'
)

target_intention = models.CharField(
verbose_name='Target intention',
max_length=50
)

title = models.CharField(
verbose_name='Title',
max_length=255
)

text = models.TextField(
verbose_name='Text',
)


# Receivers
@receiver(post_save, sender=Task, dispatch_uid="task_saved")
def task_saved(sender, instance, created, *args, **kwargs):
# If the user creating the task is not the one assigned
if created and instance.assigned is not None and instance.assigned is not instance.created_by:
Notification.objects.create(
sender=instance.created_by,
receiver=instance.assigned,
published_date=instance.creation_date,
target_type="task",
target_id=instance.id,
target_intention="create",
title='You have been assigned to "%s"' % instance.name,
text=instance.description
)

30 changes: 30 additions & 0 deletions api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,15 @@ class Meta:

labels = BaseLabelSerializer(many=True, read_only=True)

created_by = UserSerializer(read_only=True)
created_by_id = serializers.PrimaryKeyRelatedField(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to remove this field in the serializer and just put the actual user in the created_by field when the task is created to not allow edition on this field.

For the moment i can call the API to say the creator is an other guy because the get_initial() function of the view just populate field if is not already given (say me if i'm wrong)


PS: I think we can made this population of the field in the serializer with the create function. Or if is not possible with a signal on the model when create.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The create function requires the context to have the logged in user. Instead, In my new commit, I enforce the user inside the view class.

queryset=models.User.objects.all(),
source='created_by',
write_only=True,
required=False,
allow_null=True
)

assigned = UserSerializer(read_only=True)
assigned_id = serializers.PrimaryKeyRelatedField(
queryset=models.User.objects.all(),
Expand All @@ -189,6 +198,27 @@ class Meta:
)


class NotificationSerializer(serializers.ModelSerializer):

class Meta:
model = models.Notification
fields = '__all__'

sender = UserSerializer(read_only=True)
sender_id = serializers.PrimaryKeyRelatedField(
queryset=models.User.objects.all(),
source='sender',
write_only=True
)

receiver = UserSerializer(read_only=True)
receiver_id = serializers.PrimaryKeyRelatedField(
queryset=models.User.objects.all(),
source='receiver',
write_only=True
)


class FileSerializer(serializers.ModelSerializer):

class Meta:
Expand Down
11 changes: 11 additions & 0 deletions api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@
views.UserRetrieve.as_view(),
name='users_detail'
),
# NOTIFICATION
url(
r'^notification$',
views.NotificationList.as_view(),
name='notification_list'
),
url(
r'^notification/(?P<pk>\d+)$',
views.NotificationRetrieveUpdate.as_view(),
name='notification_detail'
),
# PROJECTS
url(
r'^projects$',
Expand Down
Loading