권주희

Merge branch 'feature/item_api' into 'develop'

Feature/item api

- return json object
- setting the default function
- implement destroy item api
- update the destroy api
- implement move api
- fix the response object
- implement copy item api

See merge request !5
1 +# Generated by Django 3.0.6 on 2020-06-10 11:50
2 +
3 +from django.db import migrations, models
4 +
5 +
6 +class Migration(migrations.Migration):
7 +
8 + dependencies = [
9 + ('api', '0004_auto_20200606_0824'),
10 + ]
11 +
12 + operations = [
13 + migrations.AlterField(
14 + model_name='item',
15 + name='item_id',
16 + field=models.IntegerField(auto_created=True, primary_key=True, serialize=False),
17 + ),
18 + ]
1 +# Generated by Django 3.0.6 on 2020-06-10 12:09
2 +
3 +from django.db import migrations, models
4 +
5 +
6 +class Migration(migrations.Migration):
7 +
8 + dependencies = [
9 + ('api', '0005_auto_20200610_1150'),
10 + ]
11 +
12 + operations = [
13 + migrations.AlterField(
14 + model_name='item',
15 + name='item_id',
16 + field=models.AutoField(primary_key=True, serialize=False),
17 + ),
18 + ]
1 +# Generated by Django 3.0.6 on 2020-06-10 12:17
2 +
3 +from django.db import migrations, models
4 +
5 +
6 +class Migration(migrations.Migration):
7 +
8 + dependencies = [
9 + ('api', '0006_auto_20200610_1209'),
10 + ]
11 +
12 + operations = [
13 + migrations.AlterField(
14 + model_name='item',
15 + name='updated_time',
16 + field=models.DateTimeField(null=True),
17 + ),
18 + ]
...@@ -2,7 +2,7 @@ from django.db import models ...@@ -2,7 +2,7 @@ from django.db import models
2 2
3 # Create your models here. 3 # Create your models here.
4 class Item(models.Model): 4 class Item(models.Model):
5 - item_id = models.IntegerField(primary_key = True) 5 + item_id = models.AutoField(primary_key = True)
6 is_folder = models.BooleanField(default = False) 6 is_folder = models.BooleanField(default = False)
7 name = models.CharField(max_length = 50) 7 name = models.CharField(max_length = 50)
8 path = models.TextField() 8 path = models.TextField()
...@@ -12,7 +12,7 @@ class Item(models.Model): ...@@ -12,7 +12,7 @@ class Item(models.Model):
12 size = models.IntegerField() 12 size = models.IntegerField()
13 is_deleted = models.BooleanField(default = False) 13 is_deleted = models.BooleanField(default = False)
14 created_time = models.DateTimeField(auto_now=True) 14 created_time = models.DateTimeField(auto_now=True)
15 - updated_time = models.DateTimeField() 15 + updated_time = models.DateTimeField(null=True)
16 status = models.BooleanField() 16 status = models.BooleanField()
17 17
18 #file = models.FileField(upload_to = \path) 18 #file = models.FileField(upload_to = \path)
......
...@@ -18,7 +18,3 @@ class ItemSerializer(serializers.ModelSerializer): ...@@ -18,7 +18,3 @@ class ItemSerializer(serializers.ModelSerializer):
18 model = Item 18 model = Item
19 fields = '__all__' 19 fields = '__all__'
20 20
21 -class SharedItemSerializer(serializers.ModelSerializer):
22 - class Meta:
23 - model = Item
24 - fields = '__all__'
......
1 import mimetypes 1 import mimetypes
2 import json 2 import json
3 import os 3 import os
4 +from datetime import datetime
5 +
4 import boto3 6 import boto3
5 7
6 from django.contrib.auth.models import User 8 from django.contrib.auth.models import User
...@@ -8,15 +10,12 @@ from django.core import serializers ...@@ -8,15 +10,12 @@ from django.core import serializers
8 from django.views.decorators.csrf import csrf_exempt 10 from django.views.decorators.csrf import csrf_exempt
9 from rest_framework import viewsets 11 from rest_framework import viewsets
10 from rest_framework import permissions 12 from rest_framework import permissions
11 -from rest_framework.views import APIView
12 from rest_framework.response import Response 13 from rest_framework.response import Response
13 from rest_framework.decorators import action 14 from rest_framework.decorators import action
14 -from rest_framework.parsers import JSONParser
15 from rest_framework.permissions import IsAuthenticated, AllowAny 15 from rest_framework.permissions import IsAuthenticated, AllowAny
16 16
17 from api.models import Item, SharedItem 17 from api.models import Item, SharedItem
18 -from api.serializers import UserSerializer,GroupSerializer,ItemSerializer,SharedItemSerializer 18 +from api.serializers import UserSerializer,GroupSerializer,ItemSerializer
19 -from rest_framework import generics
20 from rest_framework import status 19 from rest_framework import status
21 from annoying.functions import get_object_or_None 20 from annoying.functions import get_object_or_None
22 21
...@@ -29,13 +28,15 @@ class UserViewSet(viewsets.ModelViewSet): ...@@ -29,13 +28,15 @@ class UserViewSet(viewsets.ModelViewSet):
29 permission_classes = [permissions.IsAuthenticated] 28 permission_classes = [permissions.IsAuthenticated]
30 29
31 30
32 -class ItemViewSet(viewsets.ModelViewSet): 31 +class ItemViewSet(viewsets.ViewSet):
33 32
34 queryset = Item.objects.all() 33 queryset = Item.objects.all()
35 serializer_class = ItemSerializer 34 serializer_class = ItemSerializer
36 permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny, 35 permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
37 #IsOwnerOrReadOnly 36 #IsOwnerOrReadOnly
38 ] 37 ]
38 + permission_classes_by_action = {'get': [permissions.AllowAny],
39 + 'destroy': [permissions.AllowAny]}
39 40
40 # url: items/search 41 # url: items/search
41 @action(methods=['GET'], detail=False, permission_classes=[AllowAny], url_path='search', url_name='search') 42 @action(methods=['GET'], detail=False, permission_classes=[AllowAny], url_path='search', url_name='search')
...@@ -45,12 +46,109 @@ class ItemViewSet(viewsets.ModelViewSet): ...@@ -45,12 +46,109 @@ class ItemViewSet(viewsets.ModelViewSet):
45 item_list = Item.objects.filter(name__icontains = keyword) 46 item_list = Item.objects.filter(name__icontains = keyword)
46 47
47 data = serializers.serialize("json", item_list) 48 data = serializers.serialize("json", item_list)
48 - return Response({'data': {'list' : data}}, status=status.HTTP_200_OK) 49 + json_data = json.loads(data)
50 + res = []
51 + for i in json_data:
52 + t = i['fields']
53 + t['id'] = i['pk']
54 + res.append(t)
55 + return Response({'data': {'list' : res}}, status=status.HTTP_200_OK)
56 +
57 + # url: items/11/
58 + # 마지막 slash도 써주어야함
59 + def get(self, request, pk):
60 + print(pk)
61 + return Response({'message': "info complete"}, status=status.HTTP_200_OK)
62 +
63 + # url: items/11/
64 + # 마지막 slash도 써주어야함
65 + def destroy(self, request, pk):
66 + if request.method == 'DELETE':
67 + print(pk)
68 + item = get_object_or_None(Item, item_id=pk)
69 + if item != None:
70 + if item.is_folder == True: # 폴더는 삭제 안되도록 처리
71 + return Response({'message': 'This item is folder.'}, status=status.HTTP_200_OK)
72 + item.is_deleted = True
73 + item.save()
74 + # item.delete() 이거 하면 완전 삭제되어버림 is deleted True 면 휴지통에서 리스트 조회할 수 있도록!
75 + return Response({'message': 'delete complete'},status=status.HTTP_200_OK)
76 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
77 +
78 + # url: items/11/move
79 + # 마지막 slash도 써주어야함
80 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='move', url_name='move')
81 + def move(self, request, pk):
82 + if request.method == 'POST':
83 + parent_id = request.POST.get('parent', '')
84 + name = request.POST.get('name','')
85 + parent = get_object_or_None(Item, item_id=parent_id)
86 + if parent != None and parent.is_folder == True:
87 + child = get_object_or_None(Item, item_id=pk)
88 + if child == None:
89 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
90 + child.parent = parent_id
91 + child.save()
92 + child = Item.objects.filter(item_id = pk)
93 + child_data = serializers.serialize("json", child)
94 + json_child = json.loads(child_data)
95 + res = json_child[0]['fields']
96 + res['id'] = pk
97 + parent = Item.objects.filter(item_id = parent_id)
98 + parent_data = serializers.serialize("json", parent)
99 + json_parent = json.loads(parent_data)[0]['fields']
100 + res['parentInfo'] = json_parent
101 + return Response({'data': res}, status=status.HTTP_200_OK)
102 + if parent == None:
103 + return Response({'message': 'parent is not existed.'}, status=status.HTTP_200_OK)
104 + if parent.is_folder == False:
105 + return Response({'message': 'parent is not folder.'}, status=status.HTTP_200_OK)
106 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
107 +
108 + @action(methods=['POST'], detail=True, permission_classes=[AllowAny], url_path='copy', url_name='copy')
109 + def copy(self, request, pk):
110 + if request.method == 'POST':
111 + parent_id = request.POST.get('parent', '')
112 + parent = get_object_or_None(Item, item_id=parent_id)
113 + if parent != None and parent.is_folder == True:
114 + child = get_object_or_None(Item, item_id=pk)
115 + if child == None:
116 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
117 + if child.is_folder == True:
118 + return Response({'message': 'item is folder'}, status=status.HTTP_204_NO_CONTENT)
119 + copiedName = child.name + "_복사본_" + str(datetime.now().strftime('%Y-%m-%d %H:%M'))
120 + copiedItem = Item(is_folder = False, name = copiedName, path =child.path, parent = parent_id, user_id= child.user_id, size=child.size, status=child.status)
121 + copiedItem.save()
122 +
123 + copiedItem = Item.objects.filter(name = copiedName)
124 + copied_data = serializers.serialize("json", copiedItem)
125 + json_data = json.loads(copied_data)
126 + res = json_data[0]['fields']
127 + res['id'] = json_data[0]['pk']
128 + parent = Item.objects.filter(item_id = parent_id)
129 + parent_data = serializers.serialize("json", parent)
130 + json_parent = json.loads(parent_data)[0]['fields']
131 + res['parentInfo'] = json_parent
132 + return Response({'data': res}, status=status.HTTP_200_OK)
133 + if parent == None:
134 + return Response({'message': 'parent is not existed.'}, status=status.HTTP_200_OK)
135 + if parent.is_folder == False:
136 + return Response({'message': 'parent is not folder.'}, status=status.HTTP_200_OK)
137 + return Response({'message': 'item is not existed.'}, status=status.HTTP_204_NO_CONTENT)
138 +
139 + def get_permissions(self):
140 + try:
141 + # return permission_classes depending on `action`
142 + return [permission() for permission in self.permission_classes_by_action[self.action]]
143 + except KeyError:
144 + # action is not set return default permission_classes
145 + return [permission() for permission in self.permission_classes]
146 +
49 147
50 class SharedItemViewSet(viewsets.ModelViewSet): 148 class SharedItemViewSet(viewsets.ModelViewSet):
51 149
52 queryset = SharedItem.objects.all() 150 queryset = SharedItem.objects.all()
53 - serializer_class = SharedItemSerializer 151 + # serializer_class = SharedItemSerializer
54 permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny, 152 permission_classes = [permissions.IsAuthenticatedOrReadOnly, permissions.AllowAny,
55 # IsOwnerOrReadOnly 153 # IsOwnerOrReadOnly
56 ] 154 ]
...@@ -66,7 +164,7 @@ class SharedItemViewSet(viewsets.ModelViewSet): ...@@ -66,7 +164,7 @@ class SharedItemViewSet(viewsets.ModelViewSet):
66 sharedfile = get_object_or_None(SharedItem, item_id=pk) 164 sharedfile = get_object_or_None(SharedItem, item_id=pk)
67 if sharedfile != None: 165 if sharedfile != None:
68 # 서버는 정상이나 이미 공유객체로 등록된 파일임 166 # 서버는 정상이나 이미 공유객체로 등록된 파일임
69 - return Response({'Message': 'This file is already shared'}, status=status.HTTP_200_OK) 167 + return Response({'message': 'This file is already shared'}, status=status.HTTP_200_OK)
70 sharedfile = SharedItem(item_id =pk, password=password, expires = expires) 168 sharedfile = SharedItem(item_id =pk, password=password, expires = expires)
71 sharedfile.save() 169 sharedfile.save()
72 sharedfile = SharedItem.objects.get(item_id = pk) 170 sharedfile = SharedItem.objects.get(item_id = pk)
...@@ -75,5 +173,12 @@ class SharedItemViewSet(viewsets.ModelViewSet): ...@@ -75,5 +173,12 @@ class SharedItemViewSet(viewsets.ModelViewSet):
75 item = Item.objects.filter(item_id = pk) 173 item = Item.objects.filter(item_id = pk)
76 item_json = serializers.serialize("json", item) 174 item_json = serializers.serialize("json", item)
77 175
78 - # data = serializers.serialize("json", item_list)
79 - return Response({"shared": sharedfile.created_time , 'data': item_json}, status=status.HTTP_200_OK)
...\ No newline at end of file ...\ No newline at end of file
176 + json_data = json.loads(item_json)
177 + print(json_data)
178 + res = json_data[0]['fields']
179 + res['id'] = json_data[0]['pk']
180 + return Response({"shared": sharedfile.created_time , 'data': res}, status=status.HTTP_200_OK)
181 +
182 +item = ItemViewSet.as_view({
183 + 'delete': 'destroy',
184 +})
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -31,5 +31,7 @@ urlpatterns = [ ...@@ -31,5 +31,7 @@ urlpatterns = [
31 path('', include(router.urls)), 31 path('', include(router.urls)),
32 url(r'^search/$', views.ItemViewSet.search, name='search'), 32 url(r'^search/$', views.ItemViewSet.search, name='search'),
33 url(r'^<int:pk>/share/$', views.SharedItemViewSet.share, name='share'), 33 url(r'^<int:pk>/share/$', views.SharedItemViewSet.share, name='share'),
34 + url(r'^<int:pk>/move/$', views.ItemViewSet.move, name='move'),
35 + url(r'^<int:pk>/copy/$', views.ItemViewSet.copy, name='copy'),
34 36
35 ] 37 ]
......