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
Showing
7 changed files
with
173 additions
and
16 deletions
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 | ] | ... | ... |
-
Please register or login to post a comment