Skip to content
Open
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
5 changes: 3 additions & 2 deletions api/admin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.contrib import admin
from .models import Todo
from .models import Collaborator, Todo

admin.site.register(Todo)
admin.site.register(Todo)
admin.site.register(Collaborator)
24 changes: 24 additions & 0 deletions api/migrations/0003_collaborator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 3.0.7 on 2021-08-08 08:06

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', '0002_todo_creator'),
]

operations = [
migrations.CreateModel(
name='Collaborator',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('collab', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('todo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.Todo')),
],
),
]
9 changes: 8 additions & 1 deletion api/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,11 @@ class Todo(models.Model):
title = models.CharField(max_length=255)

def __str__(self):
return self.title
return self.title

class Collaborator(models.Model):
todo = models.ForeignKey(Todo, on_delete=models.CASCADE)
collab = models.ForeignKey(User, on_delete=models.CASCADE)

def __str__(self):
return self.collab.first_name +" "+ self.collab.last_name + "- " + self.todo.title
37 changes: 20 additions & 17 deletions api/serializers.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,9 @@
from django.contrib.auth.models import User
from rest_framework import serializers
from .models import Todo


"""
TODO:
Create the appropriate Serializer class(es) for implementing
Todo GET (List and Detail), PUT, PATCH and DELETE.
"""

from .models import Todo, Collaborator
from authentication.serializers import UserSerializer

class TodoCreateSerializer(serializers.ModelSerializer):
"""
TODO:
Currently, the /todo/create/ endpoint returns only 200 status code,
after successful Todo creation.

Modify the below code (if required), so that this endpoint would
also return the serialized Todo data (id etc.), alongwith 200 status code.
"""
def save(self, **kwargs):
data = self.validated_data
user = self.context['request'].user
Expand All @@ -27,3 +13,20 @@ def save(self, **kwargs):
class Meta:
model = Todo
fields = ('id', 'title',)

class TodoCollabSerializer(serializers.ModelSerializer):
collab_username = serializers.CharField(max_length=255, required=True)
def save(self, id, **kwargs):
data = self.validated_data
user = self.context['request'].user
username = data['collab_username']
collab = User.objects.filter(username=username)[0]
todo = Todo.objects.filter(creator=user, pk=id)[0]
if todo:
collaboration = Collaborator.objects.create(todo=todo, collab=collab)
return collaboration

class Meta:
model = Collaborator
fields = ('collab_username',)

6 changes: 5 additions & 1 deletion api/urls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from django.urls import path
from .views import TodoCreateView
from .views import TodoCreateView, TodoGetView, TodoOperationsView, TodoAddCollabView, TodoRemoveCollabView

"""
TODO:
Expand All @@ -9,4 +9,8 @@

urlpatterns = [
path('todo/create/', TodoCreateView.as_view()),
path('todo/', TodoGetView.as_view()),
path('todo/<int:id>/', TodoOperationsView.as_view()),
path('todo/<int:id>/add-collaborators/', TodoAddCollabView.as_view()),
path('todo/<int:id>/remove-collaborators/', TodoRemoveCollabView.as_view())
]
136 changes: 113 additions & 23 deletions api/views.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,125 @@
from rest_framework import generics
import re
from django.contrib.auth.models import User
from rest_framework import generics, serializers
from rest_framework import permissions
from rest_framework import status
from rest_framework import response
from rest_framework.response import Response
from .serializers import TodoCreateSerializer
from .models import Todo


"""
TODO:
Create the appropriate View classes for implementing
Todo GET (List and Detail), PUT, PATCH and DELETE.
"""

from .serializers import TodoCreateSerializer, TodoCollabSerializer
from api.serializers import TodoCollabSerializer
from .models import Todo, Collaborator

class TodoCreateView(generics.GenericAPIView):
"""
TODO:
Currently, the /todo/create/ endpoint returns only 200 status code,
after successful Todo creation.

Modify the below code (if required), so that this endpoint would
also return the serialized Todo data (id etc.), alongwith 200 status code.
"""

permission_classes = (permissions.IsAuthenticated, )
serializer_class = TodoCreateSerializer

def post(self, request):
"""
Creates a Todo entry for the logged in user.
"""
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(status=status.HTTP_200_OK)
instance = Todo.objects.filter(creator=request.user,title=serializer.data['title'])
getTodo = self.get_serializer(instance.last())

return Response(getTodo.data,status=status.HTTP_200_OK)

class TodoGetView(generics.GenericAPIView):

permission_classes = (permissions.IsAuthenticated, )
serializer_class = TodoCreateSerializer

def get(self, request):
todo=Todo.objects.filter(creator=request.user)
serializer1=self.get_serializer(todo,many=True)
todoCollab=Collaborator.objects.filter(collab=request.user)
serializer2 = []
for collabs in todoCollab:
temp=self.get_serializer(collabs.todo)
serializer2.append(temp.data)
response_data = {
"owner": serializer1.data,
"collaborator": serializer2
}
return Response(response_data,status=status.HTTP_200_OK)

class TodoOperationsView(generics.GenericAPIView):

permission_classes = (permissions.IsAuthenticated, )
serializer_class = TodoCreateSerializer

def get(self, request, id):
todo = Todo.objects.filter(creator=request.user, pk=id)
if todo:
ownership = "owner"
title=todo[0].title
else:
todo=Todo.objects.filter(pk=id)[0]
todoCollab=Collaborator.objects.filter(collab=request.user, todo=todo)[0]
ownership = "collaborator"
title=todoCollab.todo.title
response_data = {
"ownership": ownership,
"id": id,
"title": title
}
return Response(response_data, status=status.HTTP_200_OK)

def put(self, request, id):
todo = Todo.objects.filter(creator=request.user, pk=id)
if todo:
todo[0].title = request.data['title']
todo[0].save()
serializer = self.get_serializer(todo)
else:
todo=Todo.objects.filter(pk=id)[0]
todoCollab=Collaborator.objects.filter(collab=request.user, todo=todo)[0]
todoCollab.todo.title = request.data['title']
todoCollab.todo.save()
serializer = self.get_serializer(todoCollab.todo)
return Response(serializer.data, status=status.HTTP_200_OK)

def patch(self, request, id):
todo = Todo.objects.filter(creator=request.user, pk=id)
if todo:
todo[0].title = request.data['title']
todo[0].save()
serializer = self.get_serializer(todo)
else:
todo=Todo.objects.filter(pk=id)[0]
todoCollab=Collaborator.objects.filter(collab=request.user, todo=todo)[0]
todoCollab.todo.title = request.data['title']
todoCollab.todo.save()
serializer = self.get_serializer(todoCollab.todo)
return Response(serializer.data, status=status.HTTP_200_OK)

def delete(self, request, id):
todo = Todo.objects.filter(creator=request.user, pk=id)
if todo:
todo.delete()
else:
todo=Todo.objects.filter(pk=id)[0]
todoCollab=Collaborator.objects.filter(collab=request.user, todo=todo)[0]
todoCollab.todo.delete()
return Response(status=status.HTTP_204_NO_CONTENT)

class TodoAddCollabView(generics.GenericAPIView):
permission_classes = (permissions.IsAuthenticated, )
serializer_class = TodoCollabSerializer

def post(self, request, id):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save(id=id)
return Response(status=status.HTTP_201_CREATED)

class TodoRemoveCollabView(generics.GenericAPIView):
permission_classes = (permissions.IsAuthenticated, )
serializer_class = TodoCollabSerializer

def post(self, request, id):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
todo = Todo.objects.filter(creator=request.user, pk=id)[0]
collab = User.objects.filter(username=request.data['collab_username'])[0]
Collaborator.objects.filter(todo=todo, collab=collab).delete()
return Response(status=status.HTTP_204_NO_CONTENT)
39 changes: 31 additions & 8 deletions authentication/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,39 @@ class TokenSerializer(serializers.Serializer):


class LoginSerializer(serializers.Serializer):
# TODO: Implement login functionality
pass
username = serializers.CharField(max_length=255)
password = serializers.CharField(max_length=128, write_only=True)

def create(self, data):
data = self.validated_data
username = data['username']
password = data['password']
user = authenticate(username=username, password=password)
return user

class RegisterSerializer(serializers.Serializer):
# TODO: Implement register functionality
pass

first_name = serializers.CharField(max_length=128, required=True)
last_name = serializers.CharField(max_length=128)
email = serializers.EmailField(max_length=None, min_length=None, allow_blank=False)
username = serializers.CharField(max_length=255, required=True)
password = serializers.CharField(max_length=128, required=True, write_only=True)

def create(self, data):
data = self.validated_data
first_name = data['first_name']
last_name = data['last_name']
email = data['email']
username = data['username']
password = data['password']
user = User.objects.create_user(username=username, email=email, password=password)
user.first_name = first_name
user.last_name = last_name
user.save()

user = authenticate(username=username, password=password)
return user

class UserSerializer(serializers.ModelSerializer):
# TODO: Implement the functionality to display user details
pass

class Meta:
model = User
fields = ['id','first_name','last_name','username','email']
57 changes: 35 additions & 22 deletions authentication/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,53 @@
from rest_framework import status
from rest_framework.response import Response
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User
from django.contrib.auth import authenticate
from .serializers import (
LoginSerializer, RegisterSerializer, UserSerializer, TokenSerializer)


def create_auth_token(user):
"""
Returns the token required for authentication for a user.
"""
token, _ = Token.objects.get_or_create(user=user)
return token


class LoginView(generics.GenericAPIView):
"""
TODO:
Implement login functionality, taking username and password
as input, and returning the Token.
"""
pass

serializer_class = LoginSerializer

def post(self, request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.save()
if user:
token = create_auth_token(user)
response_data = {"token": "Token " + str(token)}
return Response(response_data, status=status.HTTP_200_OK)
else:
return Response(status=status.HTTP_404_NOT_FOUND)

class RegisterView(generics.GenericAPIView):
"""
TODO:
Implement register functionality, registering the user by
taking his details, and returning the Token.
"""
pass
serializer_class = RegisterSerializer

def post(self, request):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
user = serializer.save()
token = create_auth_token(user)
response_data = {"token": "Token " + str(token)}
return Response(response_data, status=status.HTTP_200_OK)

class UserProfileView(generics.RetrieveAPIView):
"""
TODO:
Implement the functionality to retrieve the details
of the logged in user.
"""
pass
permission_classes = (permissions.IsAuthenticated, )
serializer_class = UserSerializer

def get(self, request):
serializer = self.get_serializer(request.user)
response_data = {
"id": serializer.data['id'],
"name": serializer.data['first_name'] + " " + serializer.data['last_name'],
"email": serializer.data['email'],
"username": serializer.data['username']
}

return Response(response_data, status=status.HTTP_200_OK)
Loading